الخوارزميات وهياكل البيانات بلغة C++: دليل عملي

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

الخوارزميات وهياكل البيانات بلغة C++: من النظرية إلى التطبيق

\n\n

إتقان الخوارزميات وهياكل البيانات هو مرحلة أساسية في تكوين مطور محترف. بدون فهم عميق لكيفية تنظيم البيانات ومعالجتها بكفاءة، من المستحيل إنشاء تطبيقات عالية الأداء وقابلة للتوسع. توفر لغة C++ إمكانيات فريدة للعمل على مستوى منخفض مع الذاكرة وأداء عالٍ، مما يجعلها لغة مثالية لدراسة هذا الموضوع.

\n\n

في هذه المقالة، سنستعرض الخوارزميات وهياكل البيانات الأساسية بلغة C++ مع أمثلة عملية للكود يمكنك تطبيقها فورًا في مشاريعك. لن نتعمق في الحسابات الرياضية المجردة — تركيزنا على التنفيذ الحقيقي وفهم مبادئ العمل.

\n\n

1. المصفوفات الديناميكية والتعامل مع الذاكرة

\n\n

لنبدأ بالأساسيات — المصفوفات الديناميكية. على عكس المصفوفات الثابتة التي يكون حجمها ثابتًا في مرحلة التجميع، تسمح المصفوفات الديناميكية بتغيير الحجم أثناء تنفيذ البرنامج. في لغة C++، يُستخدم عامل new[] و delete[] لهذا الغرض.

\n\n
#include <iostream>\n\nint main() {\n    int size = 5;\n    int* arr = new int[size]; // تخصيص الذاكرة\n    \n    // التهيئة\n    for(int i = 0; i < size; i++) {\n        arr[i] = i * 10;\n    }\n    \n    // الإخراج\n    for(int i = 0; i < size; i++) {\n        std::cout << arr[i] << " ";\n    }\n    \n    delete[] arr; // تحرير الذاكرة\n    return 0;\n}
\n\n

من المهم تذكر أنه عند العمل مع الذاكرة الديناميكية، أنت مسؤول عن تحريرها. تسرب الذاكرة هو أحد أكثر المشكلات شيوعًا في لغة C++. يُوصى باستخدام المؤشرات الذكية (std::unique_ptr, std::shared_ptr) من المكتبة القياسية لإدارة الذاكرة تلقائيًا.

\n\n

2. المكدس والطابور: هياكل البيانات الكلاسيكية

\n\n

المكدس والطابور هما هيكلان أساسيان للبيانات يطبقان مبدأي LIFO (آخر دخول، أول خروج) و FIFO (أول دخول، أول خروج) على التوالي. دعنا نستعرض تنفيذهما بلغة C++ باستخدام مصفوفة ديناميكية.

\n\n

تنفيذ المكدس

\n\n
#include <iostream>\n#include <stdexcept>\n\nclass Stack {\nprivate:\n    int* data;\n    int capacity;\n    int top;\n    \npublic:\n    Stack(int size) : capacity(size), top(-1) {\n        data = new int[capacity];\n    }\n    \n    ~Stack() {\n        delete[] data;\n    }\n    \n    void push(int value) {\n        if(top >= capacity - 1) {\n            throw std::overflow_error("Stack overflow");\n        }\n        data[++top] = value;\n    }\n    \n    int pop() {\n        if(isEmpty()) {\n            throw std::underflow_error("Stack underflow");\n        }\n        return data[top--];\n    }\n    \n    bool isEmpty() const {\n        return top == -1;\n    }\n    \n    int peek() const {\n        if(isEmpty()) {\n            throw std::underflow_error("Stack is empty");\n        }\n        return data[top];\n    }\n};\n\nint main() {\n    Stack stack(5);\n    stack.push(10);\n    stack.push(20);\n    stack.push(30);\n    \n    std::cout << "العنصر العلوي: " << stack.peek() << std::endl;\n    std::cout << "نستخرج: " << stack.pop() << std::endl;\n    std::cout << "نستخرج: " << stack.pop() << std::endl;\n    \n    return 0;\n}
\n\n

تنفيذ الطابور

\n\n
#include <iostream>\n\nclass Queue {\nprivate:\n    int* data;\n    int capacity;\n    int front;\n    int rear;\n    int count;\n    \npublic:\n    Queue(int size) : capacity(size), front(0), rear(-1), count(0) {\n        data = new int[capacity];\n    }\n    \n    ~Queue() {\n        delete[] data;\n    }\n    \n    void enqueue(int value) {\n        if(isFull()) {\n            throw std::overflow_error("Queue overflow");\n        }\n        rear = (rear + 1) %                

المدونات

توصيات الكتب