الخوارزميات وهياكل البيانات في Swift: من المبتدئ إلى المحترف
Swift هي لغة برمجة قوية وبديهية من Apple، تُستخدم لتطوير التطبيقات لأنظمة iOS وmacOS وwatchOS وtvOS. فهم الخوارزميات وهياكل البيانات هو الأساس الذي يميز المطور المتمرس عن المبتدئ. في هذه المقالة، سنشرح المفاهيم الأساسية مع أمثلة عملية في Swift.
1. هياكل البيانات الأساسية في Swift
توفر المكتبة القياسية في Swift العديد من الهياكل المدمجة التي تشكل أساس أي تطبيق.
المصفوفات (Array)
مجموعة مرتبة من العناصر من نفس النوع. تدعم الوصول العشوائي عبر الفهرس.
var numbers: [Int] = [10, 20, 30, 40, 50]numbers.append(60)numbers.insert(5, at: 0)print(numbers[2]) // الإخراج: 30القواميس (Dictionary)
مجموعة من أزواج «مفتاح-قيمة» للبحث السريع عن البيانات باستخدام مفتاح فريد.
var userScores: [String: Int] = ["Alice": 95, "Bob": 87]userScores["Charlie"] = 92if let score = userScores["Alice"] { print("Alice's score: \\(score)")}المجموعات (Set)
مجموعة غير مرتبة من العناصر الفريدة. مثالية للتحقق من الوجود أو إزالة التكرارات.
let fruits: Set = ["Apple", "Banana", "Orange", "Apple"]print(fruits.count) // الإخراج: 3 (تمت إزالة المكرر)2. تنفيذ الكومة والطابور في Swift
الكومة والطابور هما هيكلان كلاسيكيان للبيانات، غالباً ما يتم تنفيذهما باستخدام المصفوفات.
الكومة (Stack) — LIFO (Last In, First Out)
تتم إضافة العناصر وإزالتها من نفس الطرف.
struct Stack<T> { private var elements: [T] = [] mutating func push(_ value: T) { elements.append(value) } mutating func pop() -> T? { return elements.popLast() } func peek() -> T? { return elements.last }}
var stack = Stack<Int>()stack.push(1)stack.push(2)stack.push(3)print(stack.pop()!) // الإخراج: 3الطابور (Queue) — FIFO (First In, First Out)
تتم إضافة العناصر في النهاية، وإزالتها من البداية.
struct Queue<T> { private var elements: [T] = [] mutating func enqueue(_ value: T) { elements.append(value) } mutating func dequeue() -> T? { return elements.isEmpty ? nil : elements.removeFirst() }}
var queue = Queue<String>()queue.enqueue("First")queue.enqueue("Second")print(queue.dequeue()!) // الإخراج: First3. خوارزميات الفرز والبحث
سننظر في خوارزميتين أساسيتين مفيدتين في المشاريع الحقيقية.
الفرز السريع (Quick Sort)
خوارزمية فعالة من نوع «فرق تسد» بمتوسط تعقيد O(n log n).
func quickSort(_ array: [Int]) -> [Int] { guard array.count > 1 else { return array } let pivot = array[array.count / 2] let less = array.filter { $0 < pivot } let equal = array.filter { $0 == pivot } let greater = array.filter { $0 > pivot } return quickSort(less) + equal + quickSort(greater)}
let unsorted = [3, 6, 8, 10, 1, 2, 1]print(quickSort(unsorted)) // الإخراج: [1, 1, 2, 3, 6, 8, 10]البحث الثنائي (Binary Search)
يعمل فقط على المصفوفات المرتبة. التعقيد O(log n).
func binarySearch(_ array: [Int], target: Int) -> Int? { var low = 0 var high = array.count - 1 while low <= high { let mid = (low + high) / 2 if array[mid] == target { return mid } else if array[mid] < target { low = mid + 1 } else { high = mid - 1 } } return nil}
let sortedArray = [1, 3, 5, 7, 9, 11]if let index = binarySearch(sortedArray, target: 7) { p