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

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

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

ابدأ الدورة

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



Go (Golang) هي لغة مترجمة حديثة تجمع بين أداء لغة C وبساطة لغة Python. ومع ذلك، لكتابة كود فعال بلغة Go، لا يكفي معرفة بناء الجملة. فهم الخوارزميات وهياكل البيانات هو المفتاح لإنشاء تطبيقات سريعة وقابلة للتوسع. في هذه المقالة، سنتناول ثلاثة مواضيع أساسية: البحث الثنائي، جداول التجزئة، والفرز، مع أمثلة كود حقيقية بلغة Go.



1. البحث الثنائي: السرعة والدقة



البحث الثنائي هو خوارزمية كلاسيكية للبحث عن عنصر في مصفوفة مرتبة. بدلاً من البحث الخطي (O(n))، فإنه يقلص مساحة البحث إلى النصف في كل خطوة، ويعمل بزمن O(log n). في Go، هذا مهم بشكل خاص للعمل مع الشرائح الكبيرة.



التنفيذ بلغة Go:



package main

import "fmt"

// BinarySearch ترجع فهرس العنصر إذا تم العثور عليه، وإلا ترجع -1func BinarySearch(arr []int, target int) int { left, right := 0, len(arr)-1

for left <= right { mid := left + (right-left)/2 // حماية من الفائض

if arr[mid] == target { return mid } else if arr[mid] < target { left = mid + 1 } else { right = mid - 1 } } return -1}

func main() { data := []int{2, 5, 8, 12, 16, 23, 38, 45, 56, 72} target := 23 index := BinarySearch(data, target) fmt.Printf("فهرس العنصر %d: %d", target, index) // الإخراج: فهرس العنصر 23: 5}


نصائح عملية:

  • تحقق دائمًا من أن المصفوفة مرتبة. في Go، يمكنك استخدام sort.Ints() من حزمة sort.
  • الصيغة mid := left + (right-left)/2 تمنع الفائض الصحيح في المصفوفات الكبيرة.
  • للعمل مع السلاسل النصية، استخدم sort.SearchStrings() من المكتبة القياسية.


2. جداول التجزئة: وصول سريع للبيانات



في Go، جدول التجزئة المدمج هو map. يوفر وصولاً للعناصر بزمن O(1) في المتوسط. ولكن من المهم فهم كيفية عمله داخليًا لتجنب "المزالق". يستخدم جدول التجزئة دالة تجزئة لتحويل المفتاح إلى فهرس مصفوفة (bucket). يتم حل التصادمات بطريقة السلاسل (قوائم منفصلة لكل bucket).



مثال على العمل مع map:



package main

import "fmt"

func main() { // إنشاء map scores := make(map[string]int) scores["آنا"] = 95 scores["بوريس"] = 87 scores["فيكتور"] = 92

// بحث مع التحقق من الوجود name := "بوريس" if score, exists := scores[name]; exists { fmt.Printf("درجة %s: %d", name, score) } else { fmt.Printf("الطالب %s غير موجود", name) }

// حذف delete(scores, "آنا")

// تكرار (الترتيب غير مضمون!) for key, value := range scores { fmt.Printf("%s: %d", key, value) }}


نقاط مهمة:

  • map في Go هو نوع مرجعي. عند تمريره إلى دالة، ستنعكس التغييرات على الأصل.
  • لا تستخدم map بقيمة nil للكتابة - سيؤدي ذلك إلى ذعر. قم دائمًا بالتهيئة باستخدام make().
  • ترتيب التكرار على map غير محدد. إذا كنت بحاجة إلى ترتيب، استخدم شريحة مفاتيح منفصلة.
  • للمفاتيح، يمكنك فقط استخدام الأنواع القابلة للمقارنة: الأرقام، السلاسل النصية، القيم المنطقية، المؤشرات، الهياكل بدون شرائح/map.


3. الفرز: من الفقاعي إلى السريع



تقدم Go حزمة قوية sort، والتي تنفذ الفرز السريع (quicksort) وخوارزميات أخرى. ولكن للأغراض التعليمية والفهم، من المهم كتابة الفرز يدويًا. سننظر في تنفيذين: الفرز الفقاعي (O(n²)) للبيانات الصغيرة والفرز السريع (O(n log n)) للبيانات الكبيرة.

المدونات

توصيات الكتب