Skip to content

Commit

Permalink
Day 1
Browse files Browse the repository at this point in the history
  • Loading branch information
kuanbase committed Dec 29, 2024
0 parents commit 1fe999b
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/linklist.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

158 changes: 158 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use std::ptr;
use std::fmt;
use std::fmt::Formatter;

pub struct Node<T>
{
pub value: T,
pub next: *mut Node<T>,
pub prev: *mut Node<T>,
}

impl<T> Node<T>
{
pub fn new(value: T) -> Node<T>
{
Node {value, next: ptr::null_mut(), prev: ptr::null_mut()}
}
}

pub struct LinkedList<T>
{
head: *mut Node<T>,
}

impl<T> LinkedList<T>
{
pub fn new(value: T) -> Self
{
unsafe {
Self { head: Self::new_node(value) }
}
}

/// 在鏈表頭部插入一個新節點
pub fn push_front(&mut self, value: T)
{
unsafe {
let new_node = Self::new_node(value);
let next_node = (*self.head).next;
(*self.head).next = new_node;
(*new_node).prev = self.head;
(*new_node).next = next_node;
(*next_node).prev = new_node;
}
}

pub fn pop_front(&mut self) -> Option<T>
{
unsafe {
if self.is_null()
{
return None;
}

let pop_node = (*self.head).next;
let next_node = (*pop_node).next;
(*self.head).next = next_node;
(*next_node).prev = self.head;

Self::clear_node(pop_node);

let boxed_node = Box::from_raw(pop_node);

Some(boxed_node.value)
}
}

/// 在鏈表尾部插入一個新節點
pub fn push_back(&mut self, value: T)
{
unsafe {
let new_node = Self::new_node(value);

let prev_node = (*self.head).prev;

(*new_node).next = self.head;
(*new_node).prev = prev_node;
(*prev_node).next = new_node;
(*self.head).prev = new_node;
}
}

pub fn pop_back(&mut self) -> Option<T>
{
unsafe {
if self.is_null()
{
return None;
}

let pop_node = (*self.head).prev;
let prev_node = (*pop_node).prev;

(*prev_node).next = self.head;
(*self.head).prev = prev_node;

Self::clear_node(pop_node);

let boxed_node = Box::from_raw(pop_node);

Some(boxed_node.value)
}
}

unsafe fn clear_node(node: *mut Node<T>)
{
(*node).next = ptr::null_mut();
(*node).prev = ptr::null_mut();
}

unsafe fn new_node(value: T) -> *mut Node<T>
{
let new_node = Box::into_raw(Box::new(Node::new(value)));
(*new_node).prev = new_node;
(*new_node).next = new_node;

new_node
}

unsafe fn is_null(&self) -> bool
{
(*self.head).next == self.head
}
}

impl<T> fmt::Display for LinkedList<T>
where T: fmt::Display
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
unsafe {
let mut node = (*self.head).next;

while node != self.head
{
write!(f, "{}", (*node).value)?;

if (*node).next != self.head
{
write!(f, "{}", "->")?;
}

node = (*node).next;
}

Ok(())
}
}
}

impl<T> Drop for LinkedList<T> {
fn drop(&mut self) {
while let Some(_) = self.pop_front() {}

unsafe {
let _ = Box::from_raw(self.head);
}
}
}

0 comments on commit 1fe999b

Please sign in to comment.