mirror of
https://github.com/Noratrieb/datastructures.git
synced 2026-01-15 09:55:02 +01:00
get
This commit is contained in:
parent
1c520dce45
commit
b58312c196
1 changed files with 77 additions and 9 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
type NodePtr<T> = Option<NonNull<Node<T>>>;
|
||||||
|
|
||||||
|
/// A doubly linked list with unsafe :O, except it's kind of shit compared to the std one
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LinkedList<T> {
|
pub struct LinkedList<T> {
|
||||||
start: Option<NonNull<Node<T>>>,
|
start: Option<NonNull<Node<T>>>,
|
||||||
|
|
@ -15,19 +19,66 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Node<T> {
|
pub struct Node<T> {
|
||||||
value: T,
|
value: T,
|
||||||
next: Option<NonNull<Node<T>>>,
|
next: NodePtr<T>,
|
||||||
prev: Option<NonNull<Node<T>>>,
|
prev: NodePtr<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> LinkedList<T> {
|
impl<T> LinkedList<T> {
|
||||||
pub fn new() -> Self<T> {
|
/// Creates a new empty Linked List
|
||||||
|
pub fn new() -> LinkedList<T> {
|
||||||
Self {
|
Self {
|
||||||
start: None,
|
start: None,
|
||||||
end: None,
|
end: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prepend an element to the start of the list
|
||||||
|
pub fn prepend(&mut self, element: T) {
|
||||||
|
match self.start {
|
||||||
|
None => {
|
||||||
|
let node = allocate_nonnull(Node {
|
||||||
|
value: element,
|
||||||
|
next: None,
|
||||||
|
prev: None,
|
||||||
|
});
|
||||||
|
self.start = Some(node);
|
||||||
|
self.end = Some(node);
|
||||||
|
}
|
||||||
|
Some(mut node) => {
|
||||||
|
let new = allocate_nonnull(Node {
|
||||||
|
value: element,
|
||||||
|
next: Some(node),
|
||||||
|
prev: None,
|
||||||
|
});
|
||||||
|
unsafe { node.as_mut() }.prev = Some(new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Random access over the list
|
||||||
|
pub fn get(&self, index: usize) -> Option<&T> {
|
||||||
|
dbg!(self);
|
||||||
|
Self::get_inner(self.start.as_ref(), index).map(|n| &n.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_inner(node: Option<&NonNull<Node<T>>>, index: usize) -> Option<&Node<T>> {
|
||||||
|
if let Some(ptr) = node {
|
||||||
|
match index {
|
||||||
|
0 => unsafe { Some(ptr.as_ref()) },
|
||||||
|
n => LinkedList::get_inner(Some(ptr), n - 1),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allocate_nonnull<T>(element: T) -> NonNull<T> {
|
||||||
|
let mut boxed = Box::new(element);
|
||||||
|
NonNull::new(boxed.as_mut()).expect("Allocation returned null pointer")
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IntoIterator for LinkedList<T> {
|
impl<T> IntoIterator for LinkedList<T> {
|
||||||
|
|
@ -40,7 +91,7 @@ impl<T> IntoIterator for LinkedList<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IntoIter<T> {
|
pub struct IntoIter<T> {
|
||||||
item: Option<NonNull<Node<T>>>,
|
item: NodePtr<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IntoIter<T> {
|
impl<T> IntoIter<T> {
|
||||||
|
|
@ -53,12 +104,29 @@ impl<T> Iterator for IntoIter<T> {
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let next = self.item.take();
|
//let next = self.item.take();
|
||||||
let ptr = match next {
|
//let ptr = match next {
|
||||||
None => return None,
|
// None => return None,
|
||||||
Some(mut ptr) => unsafe { ptr.as_mut() },
|
// Some(mut ptr) => unsafe { ptr.as_mut() },
|
||||||
};
|
//};
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn random_access() {
|
||||||
|
let mut list = LinkedList::new();
|
||||||
|
list.prepend("hallo");
|
||||||
|
list.prepend("test");
|
||||||
|
list.prepend("nice");
|
||||||
|
assert_eq!(list.get(0), Some(&"nice"));
|
||||||
|
assert_eq!(list.get(1), Some(&"test"));
|
||||||
|
assert_eq!(list.get(2), Some(&"hallo"));
|
||||||
|
assert_eq!(list.get(3), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue