最近在熟悉Rust,都说链表是Rust的第一个坑,今天尝试用智能指针实现一个单向链表的常见操作:头部插入、删除,尾部插入、删除,中间插入、删除,链表反转。
首先定义链表节点:
#[derive(Debug)]
struct Node {
value: i32,
next: Option<Box<Node>>,
}
节点方法:
impl Node {
fn new(value: i32) -> Box<Node> {
Box::new(Node { value, next: None })
}
fn link(&mut self, node: Box<Node>) {
self.next = Some(node);
}
}
链表结构体:
#[derive(Debug)]
struct BoxedLinkedList {
head: Option<Box<Node>>,
}
链表常见操作:
#[allow(unused)]
impl BoxedLinkedList {
fn new() -> BoxedLinkedList {
BoxedLinkedList { head: None }
}
fn is_empty(&self) -> bool {
self.head.is_none()
}
fn push_front(&mut self, value: i32) {
let mut new_node = Node::new(value);
if let Some(node) = self.head.take() {
new_node.link(node);
}
self.head = Some(new_node);
}
fn pop_front(&mut self) -> Option<i32> {
match self.head.take() {
None => None,
Some(node) => {
self.head = node.next;
Some(node.value)
}
}
}
fn push_back(&mut self, value: i32) {
let new_node = Node::new(value);
match self.head.as_mut() {
None => self.head = Some(new_node),
Some(mut curr) => {
while curr.next.is_some() {
curr = curr.next.as_mut().unwrap();
}
curr.link(new_node);
}
}
}
fn pop_back(&mut self) -> Option<i32> {
match self.head.as_mut() {
None => None,
Some(mut curr) => {
while curr.next.is_some() && curr.next.as_ref().unwrap().next.is_some() {
curr = curr.next.as_mut().unwrap();
}
match curr.next {
Some(_) => Some(curr.next.take().unwrap().value),
None => Some(self.head.take().unwrap().value),
}
}
}
}
// 按从小到大顺序插入
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) => {
if value <= curr.value {
self.push_front(value);
} else {
while curr.next.is_some() && curr.next.as_ref().unwrap().value < value {
curr = curr.next.as_mut().unwrap();
}
if let Some(node) = curr.next.take() {
new_node.link(node);
}
curr.next = Some(new_node);
}
}
}
}
fn delete(&mut self, value: i32) -> bool {
match self.head.as_mut() {
None => false,
Some(mut curr) => {
if curr.value == value {
self.head = self.head.take().unwrap().next;
true
} else {
while curr.next.is_some() && curr.next.as_ref().unwrap().value != value {
curr = curr.next.as_mut().unwrap();
}
match curr.next.take() {
None => false,
Some(node) => {
curr.next = node.next;
true
}
}
}
}
}
}
fn reverse(&mut self) {
if self.is_empty() || self.head.as_ref().unwrap().next.is_none() {
return;
}
let mut left = self.head.as_mut().unwrap().next.take();
while left.is_some() {
let mut t = left.take().unwrap();
left = t.next;
t.next = self.head.take();
self.head = Some(t);
}
}
}