مقدمة في الخوارزميات وهياكل البيانات بلغة C#
الخوارزميات وهياكل البيانات هي الأساس الذي يُبنى عليه أي برنامج عالي الجودة. في بيئة .NET ولغة C#، يتيح فهم هذه المفاهيم ليس فقط كتابة كود أكثر كفاءة، بل أيضًا اختيار الأدوات المناسبة من المكتبة القياسية الغنية (BCL — Base Class Library). يعتمد أداء التطبيق واستهلاك الذاكرة، وفي النهاية تجربة المستخدم، على اختيار هيكل البيانات المناسب.
في هذه المقالة، سنشرح هياكل البيانات والخوارزميات الرئيسية التي يجب أن يعرفها كل مطور C#. سنناقش تنفيذها، وخصائص الأداء (Big O notation)، وأمثلة عملية على الكود. المقالة مناسبة للمبتدئين والمبرمجين ذوي الخبرة الذين يرغبون في تنظيم معرفتهم.
هياكل البيانات الأساسية في C#
المصفوفات والقوائم (Array vs List)
المصفوفة (Array) هي هيكل بيانات ثابت، يخزن عناصر من نفس النوع في منطقة ذاكرة متصلة. الوصول عبر الفهرس يتم بـ O(1)، لكن إدراج وحذف العناصر (باستثناء النهاية) يتطلب O(n) بسبب الإزاحة.
int[] numbers = new int[5] { 10, 20, 30, 40, 50 };Console.WriteLine(numbers[2]); // 30List<T> هو مصفوفة ديناميكية. يزيد سعته تلقائيًا عند إضافة العناصر. داخليًا، يستخدم مصفوفة، لذا فإن سرعة الوصول عبر الفهرس هي أيضًا O(1). لكن الإدراج في المنتصف أو البداية هو O(n).
List<string> names = new List<string>() { "Анна", "Борис" };names.Add("Виктор");names.Insert(1, "Глеб"); // O(n)Console.WriteLine(names[0]); // Аннаالمكدس والطابور (Stack و Queue)
Stack<T> (المكدس) يعمل وفق مبدأ LIFO (Last In, First Out). يُستخدم في خوارزميات الاجتياز، وتحليل التعبيرات، وإدارة الاستدعاءات.
Stack<int> stack = new Stack<int>();stack.Push(1);stack.Push(2);stack.Push(3);int top = stack.Pop(); // 3Queue<T> (الطابور) يعمل وفق مبدأ FIFO (First In, First Out). يُستخدم في أنظمة معالجة المهام، وتخزين البيانات مؤقتًا.
Queue<string> queue = new Queue<string>();queue.Enqueue("Задача 1");queue.Enqueue("Задача 2");string next = queue.Dequeue(); // "Задача 1"كلا الهيكلين مبنيان على مصفوفة (مخزن مؤقت دائري) ويوفران عمليات الإدراج والحذف بمتوسط O(1).
القاموس (Dictionary)
Dictionary<TKey, TValue> هو جدول تجزئة. يوفر البحث والإدراج والحذف للعناصر بواسطة المفتاح بمتوسط O(1) (مع دالة تجزئة جيدة). هذا أحد أكثر هياكل البيانات استخدامًا في C#.
Dictionary<string, int> ages = new Dictionary<string, int>();ages["Алиса"] = 30;ages["Боб"] = 25;
if (ages.ContainsKey("Алиса")){ Console.WriteLine(ages["Алиса"]); // 30}هام: يجب أن تكون المفاتيح في Dictionary فريدة وتنفذ الواجهة IEquatable<T> أو يكون لديها GetHashCode() و Equals() معاد تعريفهما بشكل صحيح.
القائمة المرتبطة (LinkedList)
LinkedList<T> هي قائمة مزدوجة الارتباط. على عكس List، يتم الإدراج والحذف في منتصف القائمة بـ O(1) (إذا كان لديك مرجع للعقدة). لكن الوصول عبر الفهرس هو O(n). تُستخدم بشكل أقل، لكنها لا غنى عنها للطوابير ذات الوصول المزدوج وذاكرة التخزين المؤقت LRU.
LinkedList<int> list = new LinkedList<int>();list.AddLast(1);list.AddLast(2);list.AddFirst(0);
LinkedListNode<int> node = list.Find(1);list.AddAfter(node, 10); // O(1)خوارزميات الفرز والبحث في C#
الفرز السريع (QuickSort)
QuickSort —