Skip to main content

rust_algorithms/linked_list/
singly.rs

1//! Bir tomonlama bog'langan ro'yxat — `Option<Box<Node<T>>>` asosida.
2
3/// Ro'yxatning bitta tuguni: qiymat + keyingi tugunga egalik.
4#[derive(Debug)]
5struct Node<T> {
6    value: T,
7    next: Option<Box<Node<T>>>,
8}
9
10/// Bir tomonlama bog'langan ro'yxat.
11///
12/// `Option<Box<Node<T>>>` — Rustdagi eng tabiiy ko'rinish:
13/// - `None` — ro'yxat/quyruq tugadi (`NULL` ning xavfsiz muqobili);
14/// - `Box` — tugun heapda yashaydi, chunki uning o'lchami rekursiv.
15///
16/// # Misol
17/// ```
18/// use rust_algorithms::linked_list::SinglyLinkedList;
19///
20/// let mut list = SinglyLinkedList::new();
21/// list.push_front(2);
22/// list.push_front(1);
23/// list.push_back(3);
24/// assert_eq!(list.to_vec(), vec![1, 2, 3]);
25///
26/// list.reverse();
27/// assert_eq!(list.to_vec(), vec![3, 2, 1]);
28/// assert_eq!(list.pop_front(), Some(3));
29/// assert_eq!(list.len(), 2);
30/// ```
31#[derive(Debug)]
32pub struct SinglyLinkedList<T> {
33    head: Option<Box<Node<T>>>,
34    len: usize,
35}
36
37impl<T> Default for SinglyLinkedList<T> {
38    fn default() -> Self {
39        Self::new()
40    }
41}
42
43impl<T> SinglyLinkedList<T> {
44    /// Bo'sh ro'yxat.
45    pub fn new() -> Self {
46        Self { head: None, len: 0 }
47    }
48
49    /// Boshiga qo'shadi — **O(1)**, linked listning asosiy afzalligi.
50    pub fn push_front(&mut self, value: T) {
51        let yangi = Box::new(Node {
52            value,
53            next: self.head.take(), // eski boshni yangi tugunga ulaymiz
54        });
55        self.head = Some(yangi);
56        self.len += 1;
57    }
58
59    /// Boshidan oladi — **O(1)**.
60    pub fn pop_front(&mut self) -> Option<T> {
61        self.head.take().map(|node| {
62            self.head = node.next;
63            self.len -= 1;
64            node.value
65        })
66    }
67
68    /// Oxiriga qo'shadi — O(n), chunki oxirigacha yurish kerak.
69    pub fn push_back(&mut self, value: T) {
70        let yangi = Box::new(Node { value, next: None });
71        let mut kursor = &mut self.head;
72        while let Some(node) = kursor {
73            kursor = &mut node.next;
74        }
75        *kursor = Some(yangi);
76        self.len += 1;
77    }
78
79    /// Oxirgi elementni oladi — O(n).
80    pub fn pop_back(&mut self) -> Option<T> {
81        self.head.as_ref()?;
82        if self.head.as_ref()?.next.is_none() {
83            return self.pop_front();
84        }
85        let mut kursor = &mut self.head;
86        // oxirgidan oldingi tugungacha boramiz
87        loop {
88            let hozir = kursor.as_mut()?;
89            if hozir.next.as_ref()?.next.is_none() {
90                self.len -= 1;
91                return hozir.next.take().map(|n| n.value);
92            }
93            kursor = &mut kursor.as_mut()?.next;
94        }
95    }
96
97    /// Birinchi qiymatga qaraydi.
98    pub fn front(&self) -> Option<&T> {
99        self.head.as_ref().map(|n| &n.value)
100    }
101
102    /// `index` -qiymat (0 dan boshlab) — O(n).
103    pub fn get(&self, index: usize) -> Option<&T> {
104        let mut kursor = self.head.as_deref();
105        for _ in 0..index {
106            kursor = kursor?.next.as_deref();
107        }
108        kursor.map(|n| &n.value)
109    }
110
111    /// Ro'yxatni **joyida** teskari o'giradi — O(n), qo'shimcha xotirasiz.
112    ///
113    /// Klassik "uch ko'rsatkich" usuli: `prev`, `curr`, `next`.
114    /// Har qadamda joriy tugunning strelkasini orqaga qaratamiz.
115    ///
116    /// ```text
117    ///  boshida:  1 → 2 → 3 → ✕
118    ///  1-qadam:  ✕ ← 1   2 → 3 → ✕
119    ///  oxirida:  ✕ ← 1 ← 2 ← 3
120    /// ```
121    pub fn reverse(&mut self) {
122        let mut prev: Option<Box<Node<T>>> = None;
123        let mut curr = self.head.take();
124        while let Some(mut node) = curr {
125            curr = node.next.take(); // keyingisini saqlab qolamiz
126            node.next = prev; // strelkani orqaga buramiz
127            prev = Some(node);
128        }
129        self.head = prev;
130    }
131
132    /// O'rtadagi element (ikkita "ko'rsatkich" usuli: tez va sekin).
133    ///
134    /// **G'oya:** sekin ko'rsatkich 1 qadam, tez ko'rsatkich 2 qadam yuradi.
135    /// Tez ko'rsatkich oxiriga yetganda sekini roppa-rosa o'rtada bo'ladi —
136    /// ro'yxat uzunligini oldindan bilmasdan, **bitta** yurishda.
137    ///
138    /// # Misol
139    /// ```
140    /// use rust_algorithms::linked_list::SinglyLinkedList;
141    ///
142    /// let list: SinglyLinkedList<i32> = (1..=5).collect();
143    /// assert_eq!(list.middle(), Some(&3));
144    /// ```
145    pub fn middle(&self) -> Option<&T> {
146        let mut sekin = self.head.as_deref()?;
147        let mut tez = self.head.as_deref();
148
149        while let Some(t) = tez {
150            match t.next.as_deref() {
151                Some(keyingi) => {
152                    tez = keyingi.next.as_deref();
153                    sekin = sekin.next.as_deref()?;
154                }
155                None => break,
156            }
157        }
158        Some(&sekin.value)
159    }
160
161    /// Elementlar soni — O(1) (hisoblab boriladi).
162    pub fn len(&self) -> usize {
163        self.len
164    }
165
166    /// Bo'shmi?
167    pub fn is_empty(&self) -> bool {
168        self.len == 0
169    }
170
171    /// Boshidan oxirigacha iterator.
172    pub fn iter(&self) -> Iter<'_, T> {
173        Iter {
174            kursor: self.head.as_deref(),
175        }
176    }
177
178    /// Vektorga aylantiradi (nusxa olmasdan — havolalar orqali yig'adi).
179    pub fn to_vec(&self) -> Vec<T>
180    where
181        T: Clone,
182    {
183        self.iter().cloned().collect()
184    }
185}
186
187impl<T: PartialEq> SinglyLinkedList<T> {
188    /// Qiymat ro'yxatda bormi? — O(n).
189    pub fn contains(&self, value: &T) -> bool {
190        self.iter().any(|x| x == value)
191    }
192}
193
194/// [`SinglyLinkedList::iter`] qaytaradigan iterator.
195pub struct Iter<'a, T> {
196    kursor: Option<&'a Node<T>>,
197}
198
199impl<'a, T> Iterator for Iter<'a, T> {
200    type Item = &'a T;
201
202    fn next(&mut self) -> Option<Self::Item> {
203        let node = self.kursor?;
204        self.kursor = node.next.as_deref();
205        Some(&node.value)
206    }
207}
208
209impl<T> FromIterator<T> for SinglyLinkedList<T> {
210    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
211        let mut list = Self::new();
212        // Avval boshiga qo'shib, keyin teskari o'girish — O(n),
213        // har safar oxirigacha yurishdan (O(n²)) ko'ra tezroq.
214        for x in iter {
215            list.push_front(x);
216        }
217        list.reverse();
218        list
219    }
220}
221
222/// Rekursiv `Drop` stack overflow bermasligi uchun qo'lda bo'shatamiz.
223///
224/// Standart `drop` millionta tugunli ro'yxatda rekursiv chaqiriladi va stack
225/// tugab qoladi. Bu yerda tugunlarni tsikl bilan birma-bir ozod qilamiz.
226impl<T> Drop for SinglyLinkedList<T> {
227    fn drop(&mut self) {
228        let mut kursor = self.head.take();
229        while let Some(mut node) = kursor {
230            kursor = node.next.take();
231        }
232    }
233}
234
235#[cfg(test)]
236mod tests {
237    use super::*;
238
239    #[test]
240    fn push_pop_front() {
241        let mut l = SinglyLinkedList::new();
242        assert_eq!(l.pop_front(), None);
243        l.push_front(1);
244        l.push_front(2);
245        assert_eq!(l.front(), Some(&2));
246        assert_eq!(l.pop_front(), Some(2));
247        assert_eq!(l.pop_front(), Some(1));
248        assert!(l.is_empty());
249    }
250
251    #[test]
252    fn push_back_va_pop_back() {
253        let mut l = SinglyLinkedList::new();
254        assert_eq!(l.pop_back(), None);
255        for i in 1..=4 {
256            l.push_back(i);
257        }
258        assert_eq!(l.to_vec(), vec![1, 2, 3, 4]);
259        assert_eq!(l.pop_back(), Some(4));
260        assert_eq!(l.pop_back(), Some(3));
261        assert_eq!(l.len(), 2);
262        assert_eq!(l.to_vec(), vec![1, 2]);
263    }
264
265    #[test]
266    fn teskari_ogirish() {
267        let mut bosh: SinglyLinkedList<i32> = SinglyLinkedList::new();
268        bosh.reverse();
269        assert!(bosh.is_empty());
270
271        let mut l: SinglyLinkedList<i32> = (1..=5).collect();
272        l.reverse();
273        assert_eq!(l.to_vec(), vec![5, 4, 3, 2, 1]);
274        assert_eq!(l.len(), 5);
275    }
276
277    #[test]
278    fn ortasini_topish() {
279        let bosh: SinglyLinkedList<i32> = SinglyLinkedList::new();
280        assert_eq!(bosh.middle(), None);
281
282        let toq: SinglyLinkedList<i32> = (1..=5).collect();
283        assert_eq!(toq.middle(), Some(&3));
284
285        let juft: SinglyLinkedList<i32> = (1..=4).collect();
286        assert_eq!(juft.middle(), Some(&3)); // ikkinchi o'rta
287
288        let bitta: SinglyLinkedList<i32> = (1..=1).collect();
289        assert_eq!(bitta.middle(), Some(&1));
290    }
291
292    #[test]
293    fn get_va_contains() {
294        let l: SinglyLinkedList<i32> = (10..15).collect();
295        assert_eq!(l.get(0), Some(&10));
296        assert_eq!(l.get(4), Some(&14));
297        assert_eq!(l.get(5), None);
298        assert!(l.contains(&12));
299        assert!(!l.contains(&99));
300    }
301
302    #[test]
303    fn katta_royxat_stack_overflow_bermaydi() {
304        let l: SinglyLinkedList<usize> = (0..200_000).collect();
305        assert_eq!(l.len(), 200_000);
306        drop(l); // Drop implementatsiyasi tufayli panic bo'lmaydi
307    }
308}