use std::ptr::null_mut;
pub struct NodeRaw {
pub data: i32,
next: *mut NodeRaw,
}
impl NodeRaw {
pub fn new() -> Self {
Self { data: 0, next: std::ptr::null_mut() }
}
pub fn insert(&mut self, i: isize, e: i32) -> Result<(), String> {
if i < 1 {
return Err("位序从1开始".to_string());
}
let mut current = self as *mut NodeRaw;
for _ in 1..i {
unsafe {
if (*current).next.is_null() {
return Err("插入位置超出链表长度".to_string());
}
current = (*current).next;
}
}
let new_node = Box::new(NodeRaw {
data: e,
next: std::ptr::null_mut(),
});
let new_node_ptr = Box::into_raw(new_node);
unsafe {
(*new_node_ptr).next = (*current).next;
(*current).next = new_node_ptr;
}
Ok(())
}
pub fn delete(&mut self, i: isize) -> Option<Box<NodeRaw>> {
if i < 1 {
return None;
}
let mut current = &raw mut *self;
let mut pos = 0;
while pos < i - 1 {
unsafe {
if current.is_null() || (*current).next.is_null() {
return None;
}
current = (*current).next;
}
pos += 1;
}
let del = unsafe {
let del = (*current).next;
(*current).next = (*del).next;
(*del).next = null_mut();
let del = Box::from_raw(del);
del
};
Some(del)
}
pub fn get_ref(&mut self,i:isize)->Option<&i32>{
if i<1 {
return None
}
let mut current=&raw mut *self;
for _ in 0..i {
unsafe {
if current.is_null() {
return None;
}
current =(*current).next;
}
}
unsafe {
if current.is_null() {
return None;
}
let curr=&(*current).data;
Some(curr)
}
}
pub fn get_mut(&mut self,i:isize)->Option<&mut i32>{
if i<1 {
return None
}
let mut current=&raw mut *self;
for _ in 0..i {
unsafe {
if current.is_null() {
return None;
}
current =(*current).next;
}
}
unsafe {
if current.is_null() {
return None;
}
let curr=&mut (*current).data;
Some(curr)
}
}
pub fn insert_next_node(node:*mut NodeRaw,e:i32)->Result<(),LinkErr> {
if node.is_null() {
return Err(LinkErr::Node);
}
let new_node=Box::into_raw(Box::new(NodeRaw{
data:e,
next:std::ptr::null_mut(),
}));
unsafe {
(*new_node).next=(*node).next;
(*node).next=new_node;
}
Ok(())
}
}
#[derive(Debug)]
pub enum LinkErr {
Node,
Index,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_list() {
let list = NodeRaw::new();
assert_eq!(list.data, 0);
assert!(list.next.is_null());
}
#[test]
fn test_insert_at_head() {
let mut list = NodeRaw::new();
list.insert(1, 10).unwrap();
unsafe {
assert_eq!((*list.next).data, 10);
assert!((*list.next).next.is_null());
}
}
#[test]
fn test_insert_at_position() {
let mut list = NodeRaw::new();
list.insert(1, 10).unwrap();
list.insert(2, 20).unwrap();
unsafe {
assert_eq!((*list.next).data, 10);
assert_eq!((*(*list.next).next).data, 20);
}
}
#[test]
fn test_insert_invalid_position() {
let mut list = NodeRaw::new();
assert!(list.insert(0, 10).is_err());
assert!(list.insert(2, 20).is_err());
}
#[test]
fn test_delete_node() {
let mut list = NodeRaw::new();
list.insert(1, 10).unwrap();
list.insert(2, 20).unwrap();
let deleted = list.delete(1).unwrap();
assert_eq!(deleted.data, 10);
unsafe {
assert_eq!((*list.next).data, 20);
}
}
#[test]
fn test_delete_invalid_position() {
let mut list = NodeRaw::new();
assert!(list.delete(0).is_none());
assert!(list.delete(2).is_none());
}
#[test]
fn test_get_ref() {
let mut list = NodeRaw::new();
list.insert(1, 10).unwrap();
list.insert(2, 20).unwrap();
list.insert(3, 30).unwrap();
let first = list.get_ref(1).unwrap();
assert_eq!(*first, 10);
let second = list.get_ref(2).unwrap();
assert_eq!(*second, 20);
let third = list.get_ref(3).unwrap();
assert_eq!(*third, 30);
assert!(list.get_ref(4).is_none());
assert!(list.get_ref(0).is_none());
}
}
impl Drop for NodeRaw {
fn drop(&mut self) {
while !self.next.is_null() {
unsafe {
let node_to_drop = self.next;
self.next = (*node_to_drop).next;
(*node_to_drop).next = std::ptr::null_mut();
drop(Box::from_raw(node_to_drop));
}
}
}
}