JavaScript में एल्गोरिदम और डेटा स्ट्रक्चर: थ्योरी से प्रैक्टिस तक
\nएल्गोरिदम और डेटा स्ट्रक्चर के साथ काम करना किसी भी डेवलपर के लिए एक ज़रूरी स्किल है, चाहे वह किसी भी प्रोग्रामिंग लैंग्वेज का उपयोग करे। JavaScript (खासकर Node.js एनवायरनमेंट में) इसका अपवाद नहीं है। इस आर्टिकल में हम फंडामेंटल डेटा स्ट्रक्चर और क्लासिक एल्गोरिदम को शुद्ध JavaScript में इम्प्लीमेंट करके समझेंगे। आप देखेंगे कि स्टैक, क्यू, लिंक्ड लिस्ट, ट्री और सॉर्टिंग/सर्च एल्गोरिदम Node.js पर बैकएंड डेवलपमेंट की रियल-वर्ल्ड प्रॉब्लम्स में कैसे उपयोग होते हैं।
\n\n1. स्टैक और क्यू: डेटा मैनेजमेंट के लिए बेसिक स्ट्रक्चर
\nस्टैक (Stack) और क्यू (Queue) लीनियर डेटा स्ट्रक्चर हैं, जो एलिमेंट जोड़ने और हटाने के नियमों में भिन्न होते हैं। स्टैक LIFO (Last In, First Out) सिद्धांत पर काम करता है, जबकि क्यू FIFO (First In, First Out) पर।
\n\nJavaScript में स्टैक का इम्प्लीमेंटेशन
\nJavaScript में स्टैक को ऐरे या लिंक्ड लिस्ट के आधार पर बनाया जा सकता है। आइए ऐरे के साथ एक सरल वर्जन देखें:
\nclass Stack {\n constructor() {\n this.items = [];\n }\n\n push(element) {\n this.items.push(element);\n }\n\n pop() {\n if (this.isEmpty()) return null;\n return this.items.pop();\n }\n\n peek() {\n if (this.isEmpty()) return null;\n return this.items[this.items.length - 1];\n }\n\n isEmpty() {\n return this.items.length === 0;\n }\n\n size() {\n return this.items.length;\n }\n}\n\n// उपयोग का उदाहरण\nconst stack = new Stack();\nstack.push('A');\nstack.push('B');\nstack.push('C');\nconsole.log(stack.pop()); // 'C'\nconsole.log(stack.peek()); // 'B'\nस्टैक का उपयोग अक्सर ब्रैकेट बैलेंस चेक करने, ब्राउज़र में "बैक" बटन इम्प्लीमेंट करने, या ट्री को डेप्थ-फर्स्ट ट्रैवर्स करने के लिए किया जाता है।
\n\nJavaScript में क्यू का इम्प्लीमेंटेशन
\nक्यू को भी ऐरे पर बनाया जा सकता है, लेकिन बेहतर परफॉरमेंस के लिए (shift के कारण री-इंडेक्सिंग से बचने के लिए) लिंक्ड लिस्ट या दो स्टैक का उपयोग करें। यहाँ ऐरे पर एक सरल इम्प्लीमेंटेशन है:
\nclass Queue {\n constructor() {\n this.items = [];\n }\n\n enqueue(element) {\n this.items.push(element);\n }\n\n dequeue() {\n if (this.isEmpty()) return null;\n return this.items.shift();\n }\n\n front() {\n if (this.isEmpty()) return null;\n return this.items[0];\n }\n\n isEmpty() {\n return this.items.length === 0;\n }\n\n size() {\n return this.items.length;\n }\n}\n\n// उपयोग का उदाहरण\nconst queue = new Queue();\nqueue.enqueue(1);\nqueue.enqueue(2);\nqueue.enqueue(3);\nconsole.log(queue.dequeue()); // 1\nconsole.log(queue.front()); // 2\nक्यू का उपयोग टास्क मैनेजमेंट सिस्टम, BFS (ब्रेड्थ-फर्स्ट सर्च) एल्गोरिदम, और Node.js में डेटा बफरिंग (जैसे स्ट्रीम) में किया जाता है।
\n\n2. लिंक्ड लिस्ट: बार-बार इंसर्शन के लिए डायनामिक स्ट्रक्चर
\nलिंक्ड लिस्ट (Linked List) नोड्स का एक सीक्वेंस है, जहाँ प्रत्येक नोड में डेटा और अगले नोड का रेफरेंस होता है। ऐरे के विपरीत, लिस्ट के बीच में एलिमेंट इंसर्ट या डिलीट करना O(1) टाइम में होता है, बशर्ते नोड का रेफरेंस उपलब्ध हो।
\n\nसिंगली लिंक्ड लिस्ट का इम्प्लीमेंटेशन
\nclass ListNode {\n constructor(value, next = null) {\n this.value = value;\n this.next = next;\n }\n}\n\nclass LinkedList {\n constructor() {\n this.head = null;\n this.tail = null;\n this.length = 0;\n }\n\n append(value) {\n const newNode = new ListNode(value);\n if (!this.head) {\n this.head = newNode;\n this.tail = newNode;\n } else {\n this.tail.next = newNode;\n this.tail = newNode;\n }\n this.length++;\n return this;\n }\n\n prepend(value) {\n const newNode = new ListNode(value, this.head);\n this.head = newNode;\n if (!this.tail) this.tail = newNode;\n