本次学习实现链表中间的插入和删除。插入按照从小到大的顺序插入,删除则为找到要删除的值,删除节点。
一、插入
首先我们假设链表是有序的。插入的值为value,插入操作也是从头开始向后遍历链表,找到符合以下条件的节点curr:
- curr.val < value;
- curr.next.val >= value;
要考虑几种特殊情况:
- 链表为空;
- 插入的值小于头结点的值;
- 插入的值大于尾节点的值;
实现代码如下:
impl BoxedLinkedList {
fn insert(&mut self, value: i32) {
let mut new_node = Node::new(value);
match self.head.as_mut() {
None => self.head = Some(new_node), // 链表为空;
Some(mut curr) => {
// 插入值小于头节点的值;此时 curr == head;
if value <= curr.val {
self.push_front(value); // 直接调用头部插入函数;
} else {
// 遍历寻找插入位置
while curr.next.is_some() && curr.next.as_ref().unwrap().val < value {
curr = curr.next.as_mut().unwrap();
}
// 如果插入的位置不为尾节点之后;取出下一个节点并获取其所有权并link到新节点之后;
if let Some(node) = curr.next.take() {
new_node.link(node);
}
// 当前节点的next指向新节点;
curr.next = Some(new_node);
}
}
}
}
}
二、删除
查找并删除一个值。如果找不到,返回false,否则找到并删除后返回true。也要考虑链表为空、删除值为头节点的等特殊情况。这里的关键也是要找到待删除节点的前一个节点,除非已经遍历到尾部节点了。本删除方法实现只删除第一个出现的值。
实现如下:
impl BoxedLinkedList {
fn delete(&mut self, value: i32) -> bool {
match self.head.as_mut() {
None => false, // 链表为空;
Some(mut curr) => {
// 待删除节点为头节点的情况; 此时 curr == head;
if curr.val == value {
// 也可以调用 self.pop_front();这里故意给出不同实现;
self.head = self.head.take().unwrap().next;
true
} else {
// 从头节点的下一个节点开始寻找待删除节点,直到尾节点或找到为止;
while curr.next.is_some() && curr.next.as_ref().unwrap().val != value {
curr = curr.next.as_mut().unwrap();
}
// 当前curr的下一个节点的值等于value,或者curr为尾节点;
match curr.next.take() {
None => false, // curr已经是尾节点,这时相当于没有找到符合条件的节点;
Some(node) => {
// 获得下一个节点,并将其next的值的所有权转移到curr.next,删除成功;
curr.next = node.next;
true
}
}
}
}
}
}
}
插入、删除运行代码和结果如下:
fn main() {
let mut list = BoxedLinkedList::new();
for v in vec![4, 2, 8, 1, 0, 3, 9] {
list.insert(v);
}
list.display();
println!();
for v in vec![8, 2, 0, 9, 4, 22, 3, 1, 33] {
let del_rst = list.delete(v);
if del_rst {
println!("delete '{}' from the list", v);
print!("now list is : ");
list.display();
} else {
println!("cannot find the value: {}", v);
}
}
}
输出:
BoxedLinkedList { head: Some(Node { val: 0, next: Some(Node { val: 1, next: Some(Node { val: 2, next: Some(Node { val: 3, next: Some(Node { val: 4, next: Some(Node { val: 8, next: Some(Node { val: 9, next: None }) }) }) }) }) }) }) }
delete '8' from the list
now list is : BoxedLinkedList { head: Some(Node { val: 0, next: Some(Node { val: 1, next: Some(Node { val: 2, next: Some(Node { val: 3, next: Some(Node { val: 4, next: Some(Node { val: 9, next: None }) }) }) }) }) }) }
delete '2' from the list
now list is : BoxedLinkedList { head: Some(Node { val: 0, next: Some(Node { val: 1, next: Some(Node { val: 3, next: Some(Node { val: 4, next: Some(Node { val: 9, next: None }) }) }) }) }) }
delete '0' from the list
now list is : BoxedLinkedList { head: Some(Node { val: 1, next: Some(Node { val: 3, next: Some(Node { val: 4, next: Some(Node { val: 9, next: None }) }) }) }) }
delete '9' from the list
now list is : BoxedLinkedList { head: Some(Node { val: 1, next: Some(Node { val: 3, next: Some(Node { val: 4, next: None }) }) }) }
delete '4' from the list
now list is : BoxedLinkedList { head: Some(Node { val: 1, next: Some(Node { val: 3, next: None }) }) }
cannot find the value: 22
delete '3' from the list
now list is : BoxedLinkedList { head: Some(Node { val: 1, next: None }) }
delete '1' from the list
now list is : BoxedLinkedList { head: None }
cannot find the value: 33