الخوارزميات للمبتدئين: غوص عميق سهل

٢٣ سبتمبر ٢٠٢٥

Algorithms for Beginners: A Friendly Deep Dive

كلمة خوارزمية قد تبدو مخيفة عندما تبدأ للتو في البرمجة[1]. إنها تشبه مصطلحات علوم الحاسوب المخصصة للمتخصصين في الرياضيات أو المطورين ذوي الخبرة العديدة. لكن الحقيقة هي أن الخوارزميات هي مجرد تعليمات خطوة بخطوة لحل المشكلات[2]. أنت تستخدم الخوارزميات بالفعل في حياتك اليومية — مثل اتباع وصفة طبخ، أو ربط أربطة الحذاء، أو تحديد أسرع طريق للعمل. برمجة الخوارزميات تتعلق فقط بتعلم كيفية تفصيل تلك الخطوات بحيث يمكن للحواسيب اتباعها.

في هذا الدليل المطول، سنشرح الخوارزميات بطريقة ميسرة. سنعتمد على أحد أكثر لغات البرمجة تأثيرًا على الإطلاق — Lisp — لإظهار كيف تشكل الأفكار البسيطة مثل القوائم والشروط والدوال أساس التفكير الخوارزمي. Lisp أنيقة لأنها تتعامل مع الكود كبيانات والبيانات ككود[3]، مما يجعلها ملعبًا مثاليًا لاستكشاف الخوارزميات. لا تقلق إذا لم تتعامل مع Lisp من قبل. سنبدأ من الصفر، ونشرح كل مفهوم باللغة الإنجليزية البسيطة، ونمر على الأمثلة خطوة بخطوة.


ما هي الخوارزمية؟

في جوهرها، الخوارزمية هي[4]:

  • سلسلة من الخطوات تحول المدخلات إلى مخرجات.
  • حتمية، أي أنه عند إعطاء نفس المدخلات، ستنتج دائمًا نفس المخرجات.
  • محدودة، أي أنها تنتهي في النهاية.

فكر في ترتيب قائمة أسماء أبجديًا. سواء كنت تستخدم فرز الفقاعات، أو فرز سريع، أو حتى تقلب البطاقات يدويًا على مكتبك، فأنت تطبق خوارزمية.

يمكن التعبير عن الخوارزميات بلغة طبيعية، أو مخططات تدفق، أو أكواد وهمية، أو في لغات البرمجة[5]. Lisp هي واحدة من أقدم اللغات التي بدأ المطورون فيها استكشاف الخوارزميات بشكل معمق، والعديد من مفاهيم البرمجة الحديثة تعود جذورها إليها[6].


لماذا يساعد Lisp المبتدئين على فهم الخوارزميات؟

Lisp (اختصارًا لـ LISt Processing) تم تطويره بواسطة John McCarthy في MIT عام 1958[7]، مما يجعله واحدة من أقدم لغات البرمجة المستخدمة حتى اليوم. رغم عمره، لا يزال أحد أكثر الأدوات أناقة للتفكير في الخوارزميات بسبب[8]:

  • بنية لغوية موحدة: كل شيء في Lisp يبدو بنفس الشكل — تعبيرات بين قوسين[9]. هذه الوحدة تقلل من المشتتات وتجعلك تركز على كيف تعمل الخوارزمية.
  • الكود كبيانات: Lisp تعامل البرامج كقوائم، يمكن التعامل معها مثل أي بيانات أخرى[10]. هذا يفتح طرقًا قوية للتفكير في الخوارزميات.
  • تجريدات قوية: الدوال والشروط والتكرار مدمجة وسهلة التجربة[11].

لنستخدم Lisp كمرآة أثناء استكشاف أساسيات الخوارزميات.


إعداد بيئتك التجريبية

قبل الغوص في الخوارزميات، تحتاج إلى بيئة يمكنك تشغيل كود Lisp فيها. بالنسبة لـ Common Lisp، أحد أكثر الت implementations شيوعًا هو SBCL (Steel Bank Common Lisp)[12].

تثبيت SBCL

  • Linux (Ubuntu/Debian):
  sudo apt install sbcl rlwrap
  rlwrap sbcl
  • macOS (Homebrew):
  brew install sbcl rlwrap
  rlwrap sbcl
  • Windows: قم بتنزيل المثبت من موقع SBCL الرسمي[13]، وقم بتشغيله، ثم قم بتشغيل sbcl من الطرفية.

إضافة rlwrap تمنحك تجربة أفضل في سطر الأوامر مع عمل أزرار الأسهم كما هو متوقع[14].

بعد التثبيت، ستدخل إلى REPL الخاص بلغة Lisp (Read‑Eval‑Print‑Loop). اكتب (+ 1 2) واضغط Enter — مبروك، لقد قمت للتو بتشغيل أول خوارزمية: الجمع.


REPL والتعبيرات الرمزية

في Lisp، كل شيء هو تعبير[15]. هذا يعني أن كل جزء من الكود له قيمة، والمفسر يقيم هذه القيم باستمرار في REPL.

  • الأرقام: 42 يُقيّم إلى 42.
  • السلاسل: "hello" يُقيّم إلى "hello".
  • الرموز: تمثل المتغيرات أو أسماء الدوال.
  • القوائم: قلب Lisp، مكتوبة كـ (<function> <arg1> <arg2> ...)[16].

على سبيل المثال:

(+ 3 5)   ; adds 3 and 5
(* 2 4)   ; multiplies 2 and 4

هذا الهيكل المنتظم يجعل Lisp أداة ممتازة لتعلم الخوارزميات. لا يوجد فرق بين المشغلات المدمجة والدوال المعرفة من قبل المستخدم — كل شيء مجرد قائمة[17].


مكونات الخوارزميات الأساسية

عند كتابة الخوارزميات، تحتاج إلى بعض الأدوات الأساسية[18]:

1. المتغيرات

المتغيرات تخزن النتائج الوسيطة.

(let ((x 10)
      (y 20))
  (+ x y)) ; returns 30

2. الشروط

الخوارزميات غالبًا ما تتطلب منطق تفرعي[19].

defun sign-of (n)
  (cond ((< n 0) "negative")
        ((= n 0) "zero")
        (t "positive")))

3. التكرار الذاتي

العديد من الخوارزميات الكلاسيكية تكرارية[20]. على سبيل المثال، عاملي:

(defun factorial (n)
  (if (= n 0)
      1
      (* n (factorial (- n 1)))))

هذا يوضح تقسيم المشكلة إلى مشكلات فرعية أصغر — جوهر تصميم الخوارزميات[21].


الخوارزميات الكلاسيكية للمبتدئين في Lisp

لنستعرض بعض الخوارزميات الشائعة باستخدام Lisp.

1. البحث في القائمة

البحث الخطي يفحص كل عنصر حتى يجد تطابقًا[22].

(defun linear-search (item list)
  (cond ((null list) nil)
        ((equal item (car list)) t)
        (t (linear-search item (cdr list)))))
  • car يعطي العنصر الأول[23].
  • cdr يعطي باقي القائمة[24].

2. إيجاد القيمة القصوى في القائمة

(defun max-in-list (lst)
  (if (null (cdr lst))
      (car lst)
      (let ((max-rest (max-in-list (cdr lst))))
        (if (> (car lst) max-rest)
            (car lst)
            max-rest))))

3. الترتيب: فرز الإدراج

فرز الإدراج هو خوارزمية مبتدئة رائعة ذات تعقيد زمني O(n²) في أسوأ الحالات[25].

(defun insert (x sorted-list)
  (if (or (null sorted-list) (<= x (car sorted-list)))
      (cons x sorted-list)
      (cons (car sorted-list) (insert x (cdr sorted-list)))))

(defun insertion-sort (lst)
  (if (null lst)
      nil
      (insert (car lst) (insertion-sort (cdr lst)))))

جرب (insertion-sort '(5 2 9 1 6)) — سترى (1 2 5 6 9).


فهم كفاءة الخوارزميات

الخوارزميات ليست مجرد صحة؛ الكفاءة مهمة[26]. بعدان رئيسيان:

  • تعقيد الزمن: مدى الوقت الذي تستغرقه الخوارزمية مع زيادة حجم المدخلات[27].
  • تعقيد المساحة: كمية الذاكرة التي تستخدمها الخوارزمية[28].

على سبيل المثال:

  • البحث الخطي O(n) زمنيًا[29].
  • الفرز بالإدراج له تعقيد زمني O(n²) في أسوأ حالة و O(n) في أفضل حالة[30].

حتى في Lisp، يمكنك تحليل الأداء من خلال دراسة عدد الاستدعاءات التكرارية أو عدد المقارنات التي تحدث[31].


تصحيح الأخطاء والتجربة

عند تعلم الخوارزميات، الأخطاء جزء من الرحلة[32]. REPL في Lisp متسامح — إذا أدخلت شيئًا غير صحيح، يعرض لك خطأ ويسمح لك بالاستعادة. هذه حلقة التغذية الراجعة السريعة لا تقدر بثمن للتجربة مع الخوارزميات. لا تخف من تجربة الاختلافات، وكسرها، وإصلاحها.


ما وراء الأساسيات

عندما تصبح مرتاحًا مع الخوارزميات البسيطة، يفتح نظام الماكرو في Lisp الباب للبرمجة الميتا[33]. يمكنك كتابة خوارزميات تُولِّد خوارزميات أخرى. للمبتدئين، مجرد تقدير هذه الإمكانيات يكفي لتحفيزهم على الاستمرار في الاستكشاف.

على سبيل المثال، يمكنك كتابة ماكرو ينشئ تلقائيًا دوال بحث مُحسَّنة لهياكل بيانات مختلفة[34]. هذا يوضح كيف أن الخوارزميات ليست وصفات ثابتة — يمكنها التطور والتكيف.


النقاط الرئيسية

  • الخوارزميات هي مجرد إجراءات خطوة بخطوة لحل المشكلات[35].
  • Lisp بيئة رائعة لاستكشاف الخوارزميات بسبب بساطتها وقدرتها التعبيرية[36].
  • ابدأ بالوحدات الأساسية (متغيرات، شروط، استدعاء ذاتي) ثم انتقل إلى الخوارزميات الكلاسيكية مثل البحث والفرز[37].
  • الكفاءة مهمة: فكر في تعقيد الزمن والمساحة[38].
  • REPL يجعل التجربة ممتعة وتفاعلية[39].

الخاتمة

إذا كانت الخوارزميات تبدو كلمة مخيفة في الماضي، أتمنى أن يوضح لك هذا الدليل أنها مجرد خطوات منظمة لحل المشكلات. Lisp يجعل من السهل رؤية الجمال خلف الخوارزميات، من الشروط البسيطة إلى الفرز التكراري. أفضل طريقة للتعلم هي الممارسة — افتح REPL الخاص بلِسب، جرب الأمثلة، عدّلها، واخترع الخاصة بك.

الخوارزميات هي لغة حل المشكلات في علوم الحاسوب، ومع تعودك عليها، ستكتسب القدرة على مواجهة تحديات أكثر تعقيدًا[40]. اعتبر هذا خطوتك الأولى في رحلة مدى الحياة لتعلم كيفية التفكير كعالم حاسوب.

إذا أعجبك هذا الدليل، فكر في الاشتراك في نشرتي الإخبارية حيث أشارك دروسًا متعمقة، تجارب برمجية، وشرحًا مبسطًا لمفاهيم علوم الحاسوب.

برمجة سعيدة!


المراجع

[1] Khan Academy. "ما هي الخوارزمية ولماذا يجب أن تهتم؟" https://www.khanacademy.org/computing/computer-science/algorithms/

[2] Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. "مقدمة في الخوارزميات، الطبعة الرابعة." MIT Press, 2022.

[3] Wikipedia. "Lisp (لغة برمجة) - Homoiconicity." https://en.wikipedia.org/wiki/Lisp_(programming_language)

[4] Knuth, Donald. "فن برمجة الحاسوب، المجلد 1: الخوارزميات الأساسية." Addison-Wesley, 1997.

[5] Sedgewick, R. & Wayne, K. "الخوارزميات، الطبعة الرابعة." Addison-Wesley, 2011.

[6] McCarthy, John. "الدوال التكرارية للتعبيرات الرمزية وحسابها بواسطة الآلة، الجزء الأول." Communications of the ACM 3(4), 1960.

[7] Computer History Museum. "John McCarthy وميلاد Lisp." https://www.computerhistory.org/

[8] Graham, Paul. "جذور Lisp." http://www.paulgraham.com/rootsoflisp.html

[9] Steele, Guy L. "Common Lisp: اللغة، الطبعة الثانية." Digital Press, 1990.

[10] Abelson, H. & Sussman, G. J. "بنية وتفسير برامج الحاسوب." MIT Press, 1996.

[11] Touretzky, David S. "Common Lisp: مقدمة لطيفة للحساب الرمزي." Benjamin/Cummings, 1990.

[12] Steel Bank Common Lisp. "SBCL Official Documentation." http://www.sbcl.org/

[13] Steel Bank Common Lisp. "Download SBCL." http://www.sbcl.org/platform-table.html

[14] GNU Readline. "rlwrap - readline wrapper." https://GitHub.com/hanslub42/rlwrap

[15] Seibel, Peter. "Common Lisp العملي." Apress, 2005.

[16] Wikipedia. "S-expression." https://en.wikipedia.org/wiki/S-expression

[17] McCarthy, John. "تاريخ Lisp." ACM SIGPLAN Notices, 1978.

[18] Skiena, Steven S. "دليل تصميم الخوارزميات، الطبعة الثالثة." Springer, 2020.

[19] Dijkstra, Edsger W. "ملاحظات حول البرمجة المهيكلة." 1970.

[20] Roberts, Eric S. "التفكير التكراري." John Wiley & Sons, 1986.

[21] Wirth, Niklaus. "الخوارزميات + هياكل البيانات = البرامج." Prentice Hall, 1976.

[22] Knuth, Donald. "فن برمجة الحاسوب، المجلد الثالث: الفرز والبحث." Addison-Wesley, 1998.

[23] Wikipedia. "CAR and CDR." https://en.wikipedia.org/wiki/CAR_and_CDR

[24] Common Lisp HyperSpec. "Functions CAR, CDR." http://www.lispworks.com/documentation/HyperSpec/

[25] GeeksforGeeks. "تعقيد الوقت لفرز الإدراج." https://www.geeksforgeeks.org/insertion-sort/

[26] Big-O Cheat Sheet. "اعرف تعقيداتك!" https://www.bigocheatsheet.com/

[27] Sipser, Michael. "مقدمة في نظرية الحساب، الإصدار الثالث." Cengage Learning, 2012.

[28] Aho, A. V., Hopcroft, J. E., & Ullman, J. D. "هياكل البيانات والخوارزميات." Addison-Wesley, 1983.

[29] NIST. "قاموس الخوارزميات وهياكل البيانات - البحث الخطي." https://xlinux.nist.gov/dads/HTML/linearsearch.html

[30] NVIDIA Developer Blog. "شرح فرز الإدراج." https://developer.nvidia.com/blog/insertion-sort-explained/

[31] Norvig, Peter. "نماذج برمجة الذكاء الاصطناعي: دراسات حالة في Common Lisp." Morgan Kaufmann, 1992.

[32] Petzold, Charles. "الكود: اللغة المخفية لعتاد الحاسوب والبرمجيات." Microsoft Press, 2000.

[33] Graham, Paul. "حول Lisp: تقنيات متقدمة لـ Common Lisp." Prentice Hall, 1993.

[34] Queinnec, Christian. "Lisp في قطع صغيرة." Cambridge University Press, 1996.

[35] Heineman, G. T., Pollice, G., & Selkow, S. "الخوارزميات في ملخص، الإصدار الثاني." O'Reilly Media, 2016.

[36] Felleisen, M., Findler, R. B., Flatt, M., & Krishnamurthi, S. "كيفية تصميم البرامج، الإصدار الثاني." MIT Press, 2018.

[37] Bhargava, Aditya. "فهم الخوارزميات." Manning Publications, 2016.

[38] Roughgarden, Tim. "الخوارزميات المضيئة." Soundlikeyourself Publishing, 2017-2020.

[39] Seibel, Peter. "المبرمجون في العمل: انعكاسات على صناعة البرمجة." Apress, 2009.

[40] Pólya, George. "كيفية حل المسائل: جانب جديد من المنهج الرياضي." Princeton University Press, 1945.