الخوارزميات وهياكل البيانات في Swift: دليل عملي لتطبيقات iOS

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

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

ابدأ الدورة

الخوارزميات وهياكل البيانات في Swift: تطبيق عملي



Swift هي لغة برمجة قوية وبديهية، طورتها Apple لتطوير تطبيقات iOS وmacOS وwatchOS وtvOS. ومع ذلك، فإن معرفة بناء الجملة والأطر (frameworks) ليست سوى نصف النجاح. لكتابة تطبيقات فعالة وسريعة وقابلة للتوسع، من الضروري فهم كيفية عمل الخوارزميات وهياكل البيانات. في هذه المقالة، سنشرح المفاهيم الأساسية من خلال أمثلة كود محددة في Swift. ستتعلم كيفية تنفيذ المكدس والطابور وخوارزميات الفرز والبحث الثنائي، وأين تُطبق هذه المعرفة في التطوير الفعلي.



المكدس (Stack) في Swift: مبدأ LIFO عملياً



المكدس هو مجموعة تعمل وفق مبدأ "آخر ما يدخل هو أول ما يخرج" (LIFO). تخيل كومة من الأطباق: أنت تأخذ الطبق العلوي فقط. في iOS، يُستخدم المكدس مثلاً في التنقل (UINavigationController) أو في التراجع عن الإجراءات (Undo).



لننفذ مكدساً في Swift باستخدام الأدوية (Generics):



struct Stack<Element> {    private var elements: [Element] = []        mutating func push(_ element: Element) {        elements.append(element)    }        @discardableResult    mutating func pop() -> Element? {        return elements.popLast()    }        func peek() -> Element? {        return elements.last    }        var isEmpty: Bool {        return elements.isEmpty    }        var count: Int {        return elements.count    }}

// مثال على الاستخدامvar stack = Stack<String>()stack.push("الأول")stack.push("الثاني")stack.push("الثالث")

print(stack.pop()!) // الثالثprint(stack.peek()!) // الثاني


أين يُستخدم؟ في التطبيقات لعرض سجل التصفح، في المحللات (التحقق من الأقواس)، وفي خوارزميات اجتياز الرسوم البيانية (DFS).



الطابور (Queue): مبدأ FIFO لمعالجة المهام



يعمل الطابور وفق مبدأ "أول ما يدخل هو أول ما يخرج" (FIFO). مثل الطابور في المتجر: من يقف أولاً يُخدم أولاً. في Swift، يُستخدم الطابور غالباً لإدارة المهام (DispatchQueue)، ومعالجة طلبات الشبكة أو الرسوم المتحركة.



تنفيذ أساسي للطابور:



struct Queue<Element> {    private var elements: [Element] = []        mutating func enqueue(_ element: Element) {        elements.append(element)    }        @discardableResult    mutating func dequeue() -> Element? {        return isEmpty ? nil : elements.removeFirst()    }        func front() -> Element? {        return elements.first    }        var isEmpty: Bool {        return elements.isEmpty    }        var count: Int {        return elements.count    }}

// مثال على الاستخدامvar queue = Queue<Int>()queue.enqueue(1)queue.enqueue(2)queue.enqueue(3)

print(queue.dequeue()!) // 1print(queue.front()!) // 2


مشكلة الأداء: removeFirst() على المصفوفة له تعقيد O(n)، حيث يتم إزاحة جميع العناصر. للحصول على أداء عالٍ، استخدم ContiguousArray أو طابوراً ثنائي الاتجاه (deque). في المشاريع الفعلية، توصي Apple باستخدام DispatchQueue لتعدد المهام.



خوارزميات الفرز: من الفقاعي إلى الفرز السريع



الفرز هو أحد أكثر العمليات شيوعاً. في Swift، هناك دالة مدمجة sort()، لكن فهم الآليات الداخلية سيساعدك على اختيار الخوارزمية المثلى لمهمة محددة.



الفرز الفقاعي (Bubble Sort) — O(n²)

خوارزمية بسيطة ولكنها بطيئة. مفيدة للتعلم، ولكن ليس للإنتاج.



func bubbleSort(_ array: inout [Int]) {    guard array.count > 1 else { return }        for i in 0..<array.count {        var swapped = false        for j in 0..<(array.count - 1 - i) {            if array[j] > array[j + 1] {                array.swapAt(j, j + 1)                swapped =                

المدونات

توصيات الكتب