परिचय: Rust एल्गोरिदम और डेटा संरचनाओं के लिए क्यों आदर्श है
\n\nRust C/C++ के प्रदर्शन को मेमोरी सुरक्षा के साथ जोड़ता है, जो इसे एल्गोरिदम और डेटा संरचनाओं को लागू करने के लिए एक उत्कृष्ट विकल्प बनाता है। स्वामित्व (ownership) और उधार (borrowing) प्रणाली के कारण, आप बिना गार्बेज कलेक्टर के कुशल और सुरक्षित संरचनाएँ बना सकते हैं। इस लेख में, हम Rust में प्रमुख डेटा संरचनाओं और एल्गोरिदम के व्यावहारिक कार्यान्वयन पर चर्चा करेंगे - स्टैक से लेकर बाइनरी ट्री और ग्राफ ट्रैवर्सल तक।
\n\nहम केवल Rust की मानक लाइब्रेरी का उपयोग करेंगे, ताकि आप तुरंत अपने प्रोजेक्ट में कोड लागू कर सकें। सभी उदाहरण Rust 2021 संस्करण के साथ संकलित और काम करते हैं।
\n\n1. स्टैक और क्यू: Rust पर क्लासिक संरचनाएँ
\n\nस्टैक (Stack)
\n\nस्टैक LIFO (Last In, First Out) सिद्धांत पर काम करता है। Rust में, Vec के आधार पर स्टैक को लागू करना सबसे आसान है:
struct Stack<T> {\n elements: Vec<T>,\n}\n\nimpl<T> Stack<T> {\n fn new() -> Self {\n Stack { elements: Vec::new() }\n }\n\n fn push(&mut self, value: T) {\n self.elements.push(value);\n }\n\n fn pop(&mut self) -> Option<T> {\n self.elements.pop()\n }\n\n fn peek(&self) -> Option<&T> {\n self.elements.last()\n }\n\n fn is_empty(&self) -> bool {\n self.elements.is_empty()\n }\n}\n\nfn main() {\n let mut stack = Stack::new();\n stack.push(10);\n stack.push(20);\n stack.push(30);\n \n println!("शीर्ष तत्व: {:?}", stack.peek()); // Some(30)\n println!("निकाल रहे हैं: {:?}", stack.pop()); // Some(30)\n println!("स्टैक खाली है? {}", stack.is_empty()); // false\n}\n\nलाभ: Vec पहले से ही push/pop के लिए amortized O(1) प्रदान करता है, और Rust गारंटी देता है कि स्कोप से बाहर निकलने पर मेमोरी मुक्त हो जाएगी।
क्यू (Queue)
\n\nक्यू FIFO (First In, First Out) पर काम करता है। कुशल कार्यान्वयन के लिए हम मानक लाइब्रेरी से VecDeque का उपयोग करते हैं:
use std::collections::VecDeque;\n\nstruct Queue<T> {\n elements: VecDeque<T>,\n}\n\nimpl<T> Queue<T> {\n fn new() -> Self {\n Queue { elements: VecDeque::new() }\n }\n\n fn enqueue(&mut self, value: T) {\n self.elements.push_back(value);\n }\n\n fn dequeue(&mut self) -> Option<T> {\n self.elements.pop_front()\n }\n\n fn front(&self) -> Option<&T> {\n self.elements.front()\n }\n\n fn len(&self) -> usize {\n self.elements.len()\n }\n}\n\nfn main() {\n let mut queue = Queue::new();\n queue.enqueue("पहला");\n queue.enqueue("दूसरा");\n queue.enqueue("तीसरा");\n\n println!("क्यू में पहला: {:?}", queue.front()); // Some("पहला")\n println!("सेवा दे रहे हैं: {:?}", queue.dequeue()); // Some("पहला")\n println!("क्यू की लंबाई: {}", queue.len()); // 2\n}\n\nमहत्वपूर्ण: VecDeque एक रिंग बफर का उपयोग करता है, जो दोनों सिरों से इन्सर्ट और डिलीट के लिए O(1) देता है। यह क्यू के लिए Vec का उपयोग करने से काफी तेज़ है।
2. Rust में बाइनरी सर्च ट्री (BST)
\n\nबाइनरी सर्च ट्री मौलिक डेटा संरचनाओं में से एक है। हम इसे रिकर्सिव टाइप के लिए Box का उपयोग करके लागू करते हैं:
use std::cmp::Ordering;\n\n#[derive(Debug)]\nstruct Node<T: Ord> {\n value: T,\n left: Option<Box<Node<T>>>,\n right: Option<Box<Node<T>>>,\n}\n\n#[derive(Debug)]\nstruct BinarySearchTree<T: Ord> {\n root: Option<Box<Node<T>>>,\n}\n\nimpl<T: Ord> BinarySearchTree<T> {\n fn new() -> Self {\n BinarySearchTree { root: None }\n }\n\n fn insert(&mut self, value: T) {\n let mut current = &mut se