الخوارزميات وهياكل البيانات في Java: من المبتدئ إلى المطور الواثق
Java هي واحدة من أشهر لغات البرمجة في العالم، ومعرفة الخوارزميات وهياكل البيانات هي مهارة أساسية لأي مطور Java. سواء كنت تستعد لمقابلة في شركة تقنية كبرى أو ترغب ببساطة في كتابة كود أكثر كفاءة، فإن فهم هياكل البيانات الأساسية والخوارزميات في Java سيفتح لك آفاقًا جديدة. في هذه المقالة، سنستعرض المفاهيم الأساسية التي يجب أن يعرفها كل مطور، وسنعرض تنفيذها في Java مع أمثلة عملية.
1. هياكل البيانات الأساسية في Java
هياكل البيانات هي طرق لتنظيم وتخزين البيانات. توفر Java مجموعة غنية من المجموعات المضمنة، لكن فهم كيفية عملها "تحت الغطاء" سيساعدك على اتخاذ قرارات معمارية صحيحة.
1.1 المصفوفات (Arrays)
المصفوفة هي أبسط هيكل بيانات، تخزن عناصر من نفس النوع في منطقة ذاكرة متصلة. في Java، المصفوفات لها طول ثابت.
// تعريف وتهيئة مصفوفةint[] numbers = new int[5];numbers[0] = 10;numbers[1] = 20;numbers[2] = 30;numbers[3] = 40;numbers[4] = 50;
// أو مباشرة مع القيمString[] fruits = {"تفاح", "موز", "برتقال"};
// المرور عبر المصفوفةfor (int i = 0; i < fruits.length; i++) { System.out.println(fruits[i]);}
// حلقة for-each المحسنةfor (String fruit : fruits) { System.out.println(fruit);}المزايا: وصول سريع عبر الفهرس (O(1)).
العيوب: طول ثابت، صعوبة في إدراج وحذف العناصر.
1.2 القوائم المرتبطة (LinkedList)
تتكون القائمة المرتبطة من عقد، تحتوي كل عقدة على بيانات ومرجع إلى العقدة التالية (أو السابقة). في Java، هناك تطبيق مضمن java.util.LinkedList.
import java.util.LinkedList;
LinkedList<String> list = new LinkedList<>();list.add("الأول");list.add("الثاني");list.addFirst("الصفري"); // إضافة في البدايةlist.addLast("الثالث"); // إضافة في النهاية
System.out.println("العنصر الأول: " + list.getFirst());System.out.println("العنصر الأخير: " + list.getLast());System.out.println("حجم القائمة: " + list.size());
// حذف عنصرlist.remove("الثاني");المزايا: إدراج وحذف سريع في بداية/نهاية القائمة (O(1)).
العيوب: وصول بطيء عبر الفهرس (O(n)).
1.3 المكدس (Stack)
يعمل المكدس وفق مبدأ LIFO (Last In, First Out) — آخر من يدخل هو أول من يخرج. توفر Java الفئة Stack والواجهة Deque للعمل مع المكدس.
import java.util.Stack;
Stack<Integer> stack = new Stack<>();
// إضافة عناصرstack.push(10);stack.push(20);stack.push(30);
// عرض العنصر العلوي دون إزالتهSystem.out.println("العنصر العلوي: " + stack.peek()); // 30
// استخراج العنصر العلويint top = stack.pop();System.out.println("تم الاستخراج: " + top); // 30System.out.println("العلوي الجديد: " + stack.peek()); // 20
// التحقق مما إذا كان المكدس فارغًاSystem.out.println("هل المكدس فارغ؟ " + stack.isEmpty()); // falseيُستخدم المكدس غالبًا للتحقق من صحة تسلسلات الأقواس، واجتياز الأشجار، وتنفيذ خوارزميات "الرجوع/التقدم" في المتصفحات.
1.4 قائمة الانتظار (Queue)
تعمل قائمة الانتظار وفق مبدأ FIFO (First In, First Out) — أول من يدخل هو أول من يخرج. في Java، يتم تنفيذ قائمة الانتظار عبر الواجهة Queue والفئة LinkedList.
import java.util.LinkedList;import java.util.Queue;
Queue<String> queue = new LinkedList<>();
// إضافة إلى نهاية قائمة الانتظارqueue.offer("العميل 1");queue.offer("العميل 2");queue.offer("العميل 3");