Rust單鏈表

節(jié)點(diǎn)的結(jié)構(gòu)

希望鏈表存儲(chǔ)在堆上,所以使用 Box 包裹節(jié)點(diǎn) Rust 沒有空值,所以用 Option 在包裹一層

#[derive(PartialEq, Eq, Clone, Debug)]
struct ListNode<T> {
    pub data: T,
    pub next: Option<Box<ListNode<T>>>,
}

根據(jù)索引查找節(jié)點(diǎn)和找尾節(jié)點(diǎn)是通過遞歸來查找的

impl<T> ListNode<T> {
    // 新建一個(gè)節(jié)點(diǎn)
    #[inline]
    fn new(data: T) -> ListNode<T> {
        ListNode { next: None, data }
    }
    // 獲取最后的節(jié)點(diǎn)
    fn get_last_node<'a>(&'a mut self) -> &'a mut Self {
        if let Some(ref mut node) = self.next {
            return node.get_last_node();
        }
        self
    }
    // 根據(jù)索引查找節(jié)點(diǎn)
    fn get_index_node<'a>(&'a mut self, cur: usize, index: usize) -> &'a mut Self {
        if cur >= index {
            return self;
        }
        if let Some(ref mut node) = self.next {
            return node.get_index_node(cur + 1, index);
        }
        self
    }
}

鏈表的結(jié)構(gòu)

#[derive(PartialEq, Eq, Clone, Debug)]
struct List<T> {
    pub head: Option<Box<ListNode<T>>>,
    pub length: usize,
}

鏈表插入

鏈表的插入先判斷頭結(jié)點(diǎn)是否為空。如果插入的是頭結(jié)點(diǎn)的話,需要將新的節(jié)點(diǎn)的下個(gè)節(jié)點(diǎn)設(shè)置為頭結(jié)點(diǎn),再將新結(jié)點(diǎn)設(shè)置為頭節(jié)點(diǎn)。插入的是其他的位置的話,先找到索引的前一個(gè)節(jié)點(diǎn),將前一個(gè)節(jié)點(diǎn)的下個(gè)節(jié)點(diǎn)設(shè)置為新節(jié)點(diǎn),將新節(jié)點(diǎn)的下個(gè)節(jié)點(diǎn)設(shè)置為前節(jié)點(diǎn)的下個(gè)節(jié)點(diǎn)。

// 插入
fn insert(&mut self, index: usize, data: T) {
    let mut new_node = ListNode::new(data);
    if let Some(ref mut head) = self.head {
        if index == 0 {
            let head = self.head.take();
            new_node.next = head;
            self.head = Some(Box::new(new_node));
        } else {
            let mut prev_node = head.get_index_node(0, index - 1);
            let next_node = prev_node.next.take();
            new_node.next = next_node;
            prev_node.next = Some(Box::new(new_node));
        }
    } else {
        self.head = Some(Box::new(new_node));
    }
    self.length += 1
}

鏈表刪除

// 刪除
    fn delete(&mut self, index: usize) {
        if let Some(ref mut head) = self.head {
            self.length -= 1;
            if index == 0 {
                self.head = head.next.take();
            } else if index >= self.length {
                let prev_node = head.get_index_node(0, self.length - 1);
                prev_node.next.take();
            } else {
                let mut prev_node = head.get_index_node(0, index - 1);
                let mut next_node = prev_node.next.take();
                prev_node.next = next_node.as_mut().unwrap().next.take();
            }
        }
    }

鏈表的修改和查詢

  // 修改
    fn change(&mut self, mut index: usize, data: T) {
        if let Some(ref mut head) = self.head {
            if index >= self.length {
                index = self.length;
            }
            let mut node = head.get_index_node(0, index);
            node.data = data;
        }
    }
    //  查詢
    fn search(&mut self, index: usize) -> Option<T> {
        if let Some(ref mut head) = self.head {
            if index >= self.length {
                return None;
            }
            let node = head.get_index_node(0, index);
            let data = node.data;
            return Some(data);
        } else {
            return None;
        }
    }

鏈表打印

impl<T> Display for List<T>
where
    T: Debug,
{
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if let Some(head) = &self.head {
            let mut head = Some(head);
            while let Some(node) = head {
                write!(f, "{:?} => ", node.data).unwrap();
                head = node.next.as_ref();
            }
        }
        write!(f, "None")
    }
}

代碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文內(nèi)容目錄如下,會(huì)分拆為兩篇筆記,另一則筆記是 "數(shù)組和鏈表結(jié)構(gòu)(python)_1"。 3. 鏈表結(jié)構(gòu) Lin...
    import_hello閱讀 1,805評(píng)論 1 3
  • 用C寫一個(gè)鏈表 鏈表(Linked List)是一種非連續(xù)的線性數(shù)據(jù)結(jié)構(gòu),相對于數(shù)組,它允許數(shù)據(jù)在內(nèi)存中非連續(xù)存儲(chǔ)...
    xuzhougeng閱讀 822評(píng)論 0 2
  • 搞懂單鏈表常見面試題 Hello 繼上次的 搞懂基本排序算法,這個(gè)一星期,我總結(jié)了,我所學(xué)習(xí)和思考的單鏈表基礎(chǔ)知識(shí)...
    醒著的碼者閱讀 4,731評(píng)論 1 45
  • 1. 逆序打印鏈表(單鏈表) 給定單鏈表,從尾到頭打印每個(gè)節(jié)點(diǎn)的值,不同的值之間用空格隔開。比如:1>2>3>4>...
    少冰三hun甜閱讀 4,135評(píng)論 1 12
  • 數(shù)據(jù)結(jié)構(gòu) - 鏈表 鏈表(linked list):由一組被稱為結(jié)點(diǎn)(也叫節(jié)點(diǎn))的數(shù)據(jù)元素組成的數(shù)據(jù)結(jié)構(gòu),每個(gè)結(jié)點(diǎn)...
    惑也閱讀 6,234評(píng)論 0 3

友情鏈接更多精彩內(nèi)容