Kotlin में एल्गोरिदम और डेटा संरचनाएँ: सिद्धांत से अभ्यास तक
\n\nKotlin एक आधुनिक, संक्षिप्त और सुरक्षित भाषा है जिसका उपयोग Android डेवलपमेंट, बैकएंड और यहां तक कि नेटिव एप्लिकेशन के लिए सक्रिय रूप से किया जाता है। हालांकि, इसकी शक्ति पूरी तरह से तभी प्रकट होती है जब एल्गोरिदम और डेटा संरचनाओं का सही ढंग से उपयोग किया जाता है। इस लेख में, हम व्यावहारिक उदाहरणों के साथ प्रमुख अवधारणाओं का विश्लेषण करेंगे जो आपको कुशल और रखरखाव योग्य कोड लिखने में मदद करेंगे।
\n\n1. मूलभूत डेटा संरचनाएँ: सूचियाँ, स्टैक और कतारें
\n\nआइए मूल बातों से शुरू करें। Kotlin एक समृद्ध मानक लाइब्रेरी प्रदान करता है, लेकिन यह समझना कि डेटा संरचनाएँ "हुड के नीचे" कैसे काम करती हैं, अत्यंत महत्वपूर्ण है।
\n\nलिंक्ड लिस्ट (LinkedList)
\nहम मैन्युअल रूप से एक सरल सिंगली लिंक्ड लिस्ट लागू करते हैं। इससे मेमोरी और रेफरेंस के साथ काम करने के सिद्धांतों को समझने में मदद मिलेगी।
\n\nclass Node<T>(var value: T, var next: Node<T>? = null)\n\nclass LinkedList<T> {\n private var head: Node<T>? = null\n private var tail: Node<T>? = null\n\n fun add(value: T) {\n val node = Node(value)\n if (head == null) {\n head = node\n tail = node\n } else {\n tail?.next = node\n tail = node\n }\n }\n\n fun printAll() {\n var current = head\n while (current != null) {\n print("${current.value} ")\n current = current.next\n }\n println()\n }\n}\n\n// उपयोग\nfun main() {\n val list = LinkedList<Int>()\n list.add(1)\n list.add(2)\n list.add(3)\n list.printAll() // आउटपुट: 1 2 3\n}\n\nऐरे-आधारित स्टैक
\nस्टैक LIFO (Last In, First Out) सिद्धांत पर काम करता है। हम इसे Kotlin की mutableListOf का उपयोग करके लागू करते हैं।
\n\nclass Stack<T> {\n private val elements = mutableListOf<T>()\n\n fun push(item: T) = elements.add(item)\n fun pop(): T? = if (elements.isNotEmpty()) elements.removeAt(elements.size - 1) else null\n fun peek(): T? = elements.lastOrNull()\n fun isEmpty() = elements.isEmpty()\n}\n\n// उदाहरण: कोष्ठक जाँच\nfun isBalanced(expression: String): Boolean {\n val stack = Stack<Char>()\n for (char in expression) {\n when (char) {\n '(', '{', '[' -> stack.push(char)\n ')' -> if (stack.pop() != '(') return false\n '}' -> if (stack.pop() != '{') return false\n ']' -> if (stack.pop() != '[') return false\n }\n }\n return stack.isEmpty()\n}\n\nfun main() {\n println(isBalanced("({[]})")) // true\n println(isBalanced("({[})")) // false\n}\n\n2. सॉर्टिंग एल्गोरिदम: बबल सॉर्ट से क्विक सॉर्ट तक
\n\nसॉर्टिंग सबसे अधिक अध्ययन किए जाने वाले विषयों में से एक है। आइए तीन क्लासिक एल्गोरिदम देखें जिन्हें Kotlin में आसानी से लागू किया जा सकता है।
\n\nबबल सॉर्ट (Bubble Sort)
\nबड़े ऐरे के लिए सरल लेकिन अकुशल (O(n²))।
\n\nfun bubbleSort(arr: IntArray) {\n val n = arr.size\n for (i in 0 until n - 1) {\n for (j in 0 until n - i - 1) {\n if (arr[j] > arr[j + 1]) {\n val temp = arr[j]\n arr[j] = arr[j + 1]\n arr[j + 1] = temp\n }\n }\n }\n}\n\nfun main() {\n val array = intArrayOf(64, 34, 25, 12, 22, 11, 90)\n bubbleSort(array)\n println(array.joinToString()) // 11, 12, 22, 25, 34, 64, 90\n}\n\nक्विक सॉर्ट (Quick Sort)
\nऔसत मामले में सबसे तेज़ एल्गोरिदम में से एक (O(n log n))। यह रिकर्सन और ऐरे विभाजन का उपयोग करता है।
\n\nfun quickSort(arr: IntArray, low: Int, high: Int) {\n if (low < high) {\n val pi = partition(arr, low, high)\n quickSort(arr, low, pi - 1)\n quickSort(arr, pi + 1, high)\n }\n}\n\nfun partition(arr: IntArray, low: Int, high: Int): Int {\n val pivot = arr[high]\n var i = low - 1\n for (j in low until high) {\n