ماهى هياكل البيانات ؟ تخيل معي مكتبة ضخمة مليئة بالكتب مكونة من عدة طوابق بدون أي أساس يتم ترتيب هذه الكتب عليه. الاف الكتب التي تحتاج إليها بشكل مستمر ودوري وكل ما أردت البحث عن كتابٍ ما، تستغرق الساعات في البحث عنه. بالطبع عملياً، هذا لا يحدث والسبب بسيط. الأمر غير عملي تماماً ولا يمكنك إدارة مكتبة بهذه الطريقة.
وهو نفس الأمر الذي يحدث عندما نشير إلى العالم البرمجة. سواء كان مرتبط بسيرفر ما مثل سيرفرات أمازون التي يوجد بها أكثر من 150 Exabyte(مائة وخمسون مليون تيرا بايت) أو الحاسب الخاص بك أو تطبيق من التطبيقات الذي يحتاج إلى الوصول إلى مئات الميجا بايتس في الثانية الواحدة. كل هذه عمليات معقدة تتطلب كفاءة عالية توفرها هياكل البيانات.
هياكل البيانات هي طريقة لتخزين وترتيب البيانات بشكل مثالي لجعل العمليات التي ستتم عليها تحدث بأسرع قدر ممكن بالإضافة إلى استخدام أقل مساحة ممكنة. السبب الرئيسي خلف إستخدام هياكل البيانات هو توفير أكبر قدر ممكن من الوقت اللازم لتشغيل خوارزمية ما. إليك فيديو تعريفي عن هياكل البيانات.
محتوي المقال
لماذا تحتاج إلى مهارات قوية في هياكل البيانات؟
دعنا نبدأ الإجابة على هذا السؤال عن طريق إيضاح الفرق بين مفهومين مهمين، المبرمج الجيد والمبرمج السيْ. على رغم من أن التعبير قد يعتبره البعض قاسٍ نوعاً ما، ولكنه على النقيض هو حقيقي جداً. إذاً، ما الفرق بين كلٍ منهما؟
الفرق بين المبرمج الجيد والمبرمج السئ
لنقل اننا لدينا عينة من البيانات يبلغ حجمها إلى 10,000 عنصر. هذه العناصر غير مرتبة وطلب أحدهم منك ترتيب هذه العناصر. وهنا يظهر الفرق بين كلاً من المبرمج الجيد والسئ، كلاهما قادر على كتابة خوارزميةٍ ما لترتيب هذه العناصر. ولكن ما هو الوقت الذي قد تستغرقه هذه العملية. قد يضف أحدهم، ربما الفرق في جودة الكمبيوتر وليس الخورازمية نفسها، لذا قمنا بعمل تجربة على إحدى الخوارزميتين كل منهما قد تم تشغيله على<<سوبر كمبيوتر >> وكمبيوتر عادي وهذه كانت النتائج.
في المثال القبل، نستخدم اثنين من أشهر خوارزميات الترتيب وهما Quick sort و Bubble Sort. نظرياً وعملياً أداء Quick sort أفضل بكثير من أداء Bubble sort.
أوقات التشغيل لحجوم مختلفة من البيانات (حاسوب عادي مقابل حاسوب فائق)
حجم البيانات (n) | وقت Bubble Sort (حاسوب عادي) | وقت Quick Sort (حاسوب عادي) | وقت Bubble Sort (حاسوب فائق) | وقت Quick Sort (حاسوب فائق) |
---|---|---|---|---|
1,000 | 1 ثانية | ~0.01 ثانية | 0.01 ثانية | ~0.0001 ثانية |
10,000 | 100 ثوانٍ (~1.67 دقيقة) | ~0.13 ثانية | 1 ثانية | ~0.0013 ثانية |
100,000 | 10,000 ثوانٍ (~2.78 ساعة) | ~1.66 ثانية | 100 ثوانٍ (~1.67 دقيقة) | ~0.0166 ثانية |
1,000,000 | 1,000,000 ثوانٍ (~278 ساعة) | ~19.93 ثانية (~0.33 دقيقة) | 10,000 ثوانٍ (~2.78 ساعة) | ~0.20 ثانية |
10,000,000 | 100,000,000 ثوانٍ (~27,778 ساعة أو ~3.17 سنوات) | ~230.26 ثانية (~3.84 دقائق) | 1,000,000 ثوانٍ (~278 ساعة) | ~2.30 ثانية |
التحليل
تستغرق خوارزمية Bubble sort O(N^2) أضعاف أضعاف الوقت التي يستغرقه خوارزميةQuck sort O(log N). حتى إذا كررنا التجربة على حاسوب فائق تظل النتائج متباعدة بقدر كبير.
يوضح الجدول أنه بغض النظر عن قوة الحوسبة المتاحة (حاسوب عادي مقابل حاسوب فائق)، فإن كفاءة الخوارزمية تلعب دورًا حاسمًا في الأداء. تتفوق الخوارزميات الفعالة مثل Quick Sort بشكل كبير على الخوارزميات غير الفعالة مثل Bubble Sort، خاصةً مع زيادة حجم البيانات. يمكن للحاسوب الفائق تقليل أوقات التشغيل بشكل كبير، لكن تعقيد الوقت الجوهري للخوارزميات يظل عاملاً حاسمًا.
الخلاصة
أثناء عملية اختيار المرشحن لوظيفةٍ ما، هذه هي العوامل التي تحدد مدى جودة المبرمج وقابليته لإستغراق وقت أقل لتنفيذ مهمةٍ ما. هذا مثال مشهور جداً لتوضيح الفرق بين المبرمج السئ والجيد، المربمج الجيد يستطيع استخدام خوارزميات ذات جودة أفضل وأعلى لإنجاز مهمة ما بشكل أسرع، المبرمج الجيد يستطيع تطويع هياكل البيانات لإستخدام مساحة أقل.
فمثلاً إن كنت تبرمج لعبة ما، فسيتعين عليك إستخدام أقل قدر ممكن من المساحلة لتنفيذ مهمةٍ ما، ذلك حتى تكون لعبتك قادرة على أن تعمل على جميع الأجهزة بدلاً من الأجهزة التي تمتلك ذاكرة عشوائية 16 جيجا فقط. المبرمج الجيد يكتب أكواد دائما تعمل بكفاءة. فأيهما تريد أن تكون؟
** فيديو شرح هياكل البيانات **
أمثلة عملية على إستخدامات يومية لهياكل البيانات
كما ذكرنا في الفيديو، توجد إستخدامات عملية ملموسة لهياكل البيانات نستخدمها بشكل يومي دون معرفة ما يحدث في خلفية هذه العمليات. إليك المزيد من الأمثلة:
1.خاصية Alt + Tab على الويندوز
هل سبق لك أن استخدمت أكثر من برنامج على ويندوز وأردت الإنتقال سريعاً إلى احد البرامج الأخرى باستخدام Alt + Tab؟ هل سألت كيف يحتفظ ويندوز بسلاسة تلك البرامج التي تعمل في الخلفية وكيف تتيح لك التنقل بسهولة خلالها؟ الإجابة هي Linked Lists.
كما ذكرنا، Linked lists هي عبارة عن سلسلة ، كل عقدة من السلسلة تحتفظ بالبيانات الخاصة بها (في مثالنا، البيانات هي البرنامج المفتوح) كما تحتفظ تلك العقدة بعنوان العقدة التالية (في مثالنا، عنوان البرنامج التالي المفتوح) وبالتالي إذا أردت التنقل إلى برنامج أخر، يمكنك التنقل بسهولة لأن كل ما على الويندوز القيام به هو إستخراج البيانات الموجودة بداخل عنوان العقدة التالية.
2. الشبكة المكونة من الملفات على نسخة الويندوز الخاصة بك
على ويندوز، كل ((الفولدرات)) هي جزء من فولدر اخر، إلى أن تصل إلى فولدر رئيسي يصدر عنه جميع الفولدرات. هذا الفولدر الرئيسي هو ((Partition)). فرضاً، أردت أن تصل إلى فولدر ((Old)) كما هو موضح بالصورة، إذن سيتعين عليك المرور من خلال شبكة من ((الفولدرات)) للوصول إلى غايتك. هذا الهيكل من البيانات هو ما يسمى ” Tree”.
من أسمها، هي تماماً كالشجرة عدة أفرع، كل فرع يحتوي على عدة أفرع، إذا أردت البحث عن شئ ما بداخل الشجرة ، سيكون من السهل عليك الوصول له خاصةً وأنك تعرف العنوان التفصيلي.
3.خاصية تحديد الطريق على Google Maps
بالطبع أستخدمت <<Google Maps>> في إحدى المرات لتحديد وجهة ما. هل سألت نفسك من قبل كيف يستطيع جوجل تحديد الطريق الذي ترغب الوصول إليه؟ الإجابة هي Graphs.
يتكون <<Graph>> من عنصريين أساسيين. Nodes (بالعربية: عقد) و Edges(بالعربية: حواف). ببساطة كل عقدة تمثل مكان ما على الخريطة الأصلية، وكل حافة تمثل الطريق الذي يمكنك سلكه للوصول لتلك العقدة. بالتالي، يمكنك من خلال بعض الخورازميات تحديد طريقك في اجزاء من الثانية. ترجع سرعة ودقة هذه العملية لسببين رئيسيين أولهما هو خوارزميات مثالية والأخرى هي هيكل بيانات يمكنك تشغيل هذه الخورازميات عليه. وهذا ما تضمنه هياكل البيانات، وهو إنشاء هيكلة تسطيع من خلالها الخورازميات العمل بشكل مثالي. أي، ما فائدة خورازميات مثالية تعمل على بيانات منتثرة غير مصنفة على أساس؟
الفرق بين هياكل البيانات الساكنة والمرنة (Static vs Dynamic)
يوجد نوعان أساسيان من هياكل البيانات، الساكنة والمرنة سنتحدث عنهم في تلك الفقرة بالتفصيل.
1. هياكل البيانات الساكنة
عندما تنشئ Array جديد في أغلب لغات البرمجة مثل (++C و Java) يكون الأمر ضرورياً أن تحدد حجم ال<<Array>> أثناء إنشائه. وذلك لتحديد مساحةٍ ما من الذاكرة العشوائية <<RAM>> يمكنك تخزين هذه البيانات بها. بالطبع يمكنك التعديل في البيانات كيفما شئت ولكن، لا يمكنك التعديل في الحجم.
إذا أردت إضافة عنصر جديد، سيتعين عليك إنشاء Array جديد ذو حجم جديد ثم سيتعين عليك نقل العناصر القديمة إلى الArray الجديد. ما إذا أردت الحذف، فسيتعين عليك أيضاً إنشاء Array جديد ذو حجم أقل ومن ثم نقل العناصر التي تريد نقلها فقط. المهم أنه لا يمكنك تغيير المساحة التي تم تحديدها مبدأياً لاحقاً.
قد تقل لنفسك، هذه العملية غير فعالة ومكلفة، ولكن هي بها ميزات عديدة سنذكرها لاحقاً في مقارنة بين الإثنين.
أمثلة على هياكل البيانات الساكنة:
- arrays
- Structures وهي إحدى مميزات لغة ++C إن كنت من مستخدميها
- المصفوفات – Matrices
- Tuples :وهي واحدة من هياكل البيانات المستخدمة بلغة بايثون
- القواميس :Dictionaries
2. هياكل البيانات المرنة
على النقيض تماماً، هياكل البيانات المرنة لا يتم تحديد حجمها من الأساس، يمكنك إضافة عناصر أثناء تشغيل البرنامج، تم تصميمها من الأساس للحالات التي تتطلب حذف وإضافة مستمرة لهيكل البيانات. ببساطة إذا أردت إدخال عنصر جديد، قم بحجز مساحة له في الذاكرة العشوائية <<RAM>> واحتفظ بهذا العنوان(هل يذكرك هذا بالLinked Lists؟ في الحقيقة، Linked lists هو حجر الأساس لكلٍ هياكل البيانات الديناميكية).
أمثلة على هياكل البيانات المرنة:
- Queues
- Graphs
- Hash Maps
- Graphs and Networks
- Stacks
مقارنة تفصيلية بين هياكل البيانات الساكنة والديناميكية
الخاصية | هياكل البيانات الساكنة | الهياكل البيانات المرنة |
---|---|---|
تعريف | هياكل بيانات بحجم ثابت، يتم تحديد الحجم عند الإنشاء | هياكل بيانات يمكن تغيير حجمها أثناء عمل البرامج |
الذاكرة | تخصص الذاكرة مرة واحدة، وبالتالي، إدارة تلك الذاكرة والوصول إلى العناصر يكون بشكل أسهل | تخصيص وإلغاء تخصيص الذاكرة بشكل ديناميكي وبالتالي من الصعب الوصول لعنصرٍ ما لعدم معرفة مكانه بالتفصيل |
الكفاءة | يمكن أن تكون أكثر كفاءة في استخدام الذاكرة عند معرفة الحجم مسبقًا | تكون كفائتها أقل نظراً لتباعد العناصر داخل الذاكرة العشوائية |
السرعة | عادةً ما تكون أسرع نظرًا لعدم الحاجة لتغيير الحجم | يمكن أن تكون أبطأ بسبب عمليات الإضافة والحذف |
سهولة الاستخدام | بسيطة وسهلة الاستخدام، مثالية للبيانات بحجم ثابت | أكثر تعقيدًا بسبب إدارة الذاكرة والتعقيدات الإضافية |
المرونة | غير مرنة، لا يمكن تغيير الحجم بعد التخصيص | مرنة، يمكن تغيير الحجم وإضافة أو إزالة العناصر |
التخصيص المسبق | يتطلب معرفة الحجم مسبقًا | لا يتطلب معرفة الحجم مسبقًا |
توضيح
- الهياكل الثابتة للبيانات:
- المميزات: إدارة ذاكرة بسيطة، سرعة أعلى، استخدام مثالي في الحالات التي يكون فيها حجم البيانات معروف وثابت.
- العيوب: غير مرنة، تحتاج إلى معرفة الحجم مسبقًا، غير ملائمة للتغيرات الديناميكية.
- الهياكل الديناميكية للبيانات:
- المميزات: مرنة، يمكن تغيير الحجم بسهولة، لا تحتاج إلى معرفة الحجم مسبقًا، مناسبة للبيانات المتغيرة.
- العيوب: إدارة ذاكرة أكثر تعقيدًا، يمكن أن تكون أبطأ بسبب عمليات التخصيص وإلغاء التخصيص، يمكن أن تتسبب في تجزئة الذاكرة.
الفرق بين هياكل البيانات الخطية والغير خطية Linear vs Non Linear Data Structures
هياكل البيانات الخطية:
ببساطة، هياكل البيانات الخطية هي هياكل بيانات تتوالى فيها العناصر بترتيب خطي،أي واحداً تلو الاخر، يوجد أساس يتم من خلاله ترتيب تلك العناصر سوياً. أي ، لها بداية ولها نهاية. أمثلة على الهياكل الخطية:
- Arrays
- Linked Lists
- Stacks
- Linked Lists
- Hash Tables
هياكل البيانات الغير خطية:
وهي هياكل بيانات لا تعتمد على ترتيب العناصر. قد يكون أيضاً لها بداية ونهاية (في بعض الحالات ليس لديها بداية أو نهاية) ولكن على الرغم من ذلك، يكون الترتيب فرعي وغير مهم في هذه الحالات. أمثلة على هياكل البيانات الغير خطية:
- Trees
- Graphs
عن دورة هياكل البيانات المجانية التي تقدمها منصة مطور
نقدم لكم دورة مجانية تماماً في هياكل البيانات، تتضمن كل ما تحتاجه كمطور من خبرة في هياكل البيانات. سنتعرض في هذه الدورة إلى الأنواع المختلفة من هياكل البينات مثل:
- Stack
- Queues
- Linked Lists
- Arrays
- Hash Tables
- Binary Search Trees
- Heap
- Graphs
سنتناول شرح كل المواضيع بشكل تفصيلي من كتابة الأكواد الخاصة بهم، شرح لطريقة عمل كل منهما، إستخدامات كلٍ منهم، كما سنتطرق لحل بعض المشكلات سوياً والتدريب العملي على كلٍ من هذه المواضيع.
كما سنتيح لك الأكواد التي إستخدمناها بالإضافة إلى محتوى مرئي على منصة يوتيوب يتناول هذا الشرح التفصيلي بالإضافة إلى المقالات التفصيلية المتاحة على موقعنا والمحاضرات التي إستخدمناها أثناء عملية الشرح. سنغطي كافة كل ما تريده كمتعلم بشكل إحترافي تماماً.
** فيديو**