pub struct ArenaList<T> {
pub nodes: Vec<Option<T>>,
pub nexts: Vec<Option<usize>>,
pub holes: Vec<usize>,
}
impl<T> ArenaList<T> {
fn new() -> Self {
Self {
nodes: Vec::new(),
nexts: Vec::new(),
holes: Vec::new(),
}
}
fn make_node(&mut self, data: Option<T>) -> usize {
match self.holes.pop() {
Some(new_idx) => {
self.nodes[new_idx] = data;
self.nexts[new_idx] = None;
new_idx
}
None => {
self.nodes.push(data);
self.nexts.push(None);
self.nexts.len() - 1
}
}
}
}
pub struct LinkedList<'a, T> {
root: usize,
owner: &'a mut ArenaList<T>,
}
impl<'a, T> LinkedList<'a, T> {
fn from_vec(arena_list: &'a mut ArenaList<T>, vec1: Vec<T>) -> Self {
let dummy = arena_list.make_node(None);
let mut prev = dummy;
for data in vec1 {
let curr = arena_list.make_node(Some(data));
arena_list.nexts[prev] = Some(curr);
prev = curr;
}
Self {
root: dummy,
owner: arena_list,
}
}
fn clear() {}
fn to_vec(&self) -> Vec<&T> {
let mut res = Vec::new();
let mut curr_idx = self.root;
loop {
match self.owner.nexts[curr_idx] {
Some(next_idx) => {
match &self.owner.nodes[next_idx] {
Some(node_data) => res.push(node_data),
None => break
}
curr_idx = next_idx;
}
None => break
}
}
res
}
fn get(&self, mut num: usize) -> &Option<T> {
let mut curr_idx = self.root;
loop {
match self.owner.nexts[curr_idx] {
Some(next_idx) => {
if num == 0 {
return &self.owner.nodes[next_idx];
}
curr_idx = next_idx;
num -= 1;
}
None => { return &None; }
}
}
}
fn insert(&mut self, mut num: usize, data: T) {
let new_idx = self.owner.make_node(Some(data));
let mut curr_idx = self.root;
loop {
match self.owner.nexts[curr_idx] {
Some(next_idx) => {
if num == 0 {
self.owner.nexts[new_idx] = Some(next_idx);
self.owner.nexts[curr_idx] = Some(new_idx);
curr_idx = new_idx;
break;
}
curr_idx = next_idx;
num -= 1;
}
None => break
}
}
}
fn del(&mut self, mut num: usize) -> bool {
let mut curr_idx = self.root;
loop {
match self.owner.nexts[curr_idx] {
Some(next_idx) => {
if num == 0 {
self.owner.nexts[curr_idx] = self.owner.nexts[next_idx];
self.owner.nexts[next_idx] = None;
self.owner.nodes[next_idx] = None;
self.owner.holes.push(next_idx);
return true;
}
curr_idx = next_idx;
num -= 1;
}
None => {
return false;
}
}
}
}
}
impl<'a, T> LinkedList<'a, T> {
fn split(&mut self, mut num: usize) -> LinkedList<T> {
let dummy = self.owner.make_node(None);
let mut curr_idx = self.root;
loop {
match self.owner.nexts[curr_idx] {
Some(next_idx) => {
if num == 0 {
self.owner.nexts[dummy] = Some(next_idx);
self.owner.nexts[curr_idx] = None;
break;
}
curr_idx = next_idx;
num -= 1;
}
None => { break; }
}
}
LinkedList { root: dummy, owner: self.owner }
}
}
#[cfg(test)]
mod tests {
use crate::linked_list::{ArenaList, LinkedList};
#[test]
fn test1() {
let mut arena_list = ArenaList::new();
let vec1 = vec![1, 2, 3, 4, 5, 6];
let mut linked_list = LinkedList::from_vec(&mut arena_list, vec1);
println!("{:?}", linked_list.to_vec());
linked_list.insert(3, 9);
linked_list.insert(0, 99);
println!("{:?}", linked_list.to_vec());
println!("index = {}, val = {:?}", 0, linked_list.get(0));
println!("index = {}, val = {:?}", 3, linked_list.get(3));
println!("index = {}, val = {:?}", 8, linked_list.get(8));
linked_list.del(3);
linked_list.del(2);
println!("{:?}", linked_list.to_vec());
}
#[test]
fn test2() {
let mut arena_list = ArenaList::new();
let vec1 = vec![1, 2, 3, 4, 5, 6];
let mut linked_list1 = LinkedList::from_vec(&mut arena_list, vec1);
let mut linked_list2 = linked_list1.split(3);
println!("{:?}", linked_list2.to_vec());
println!("{:?}", linked_list1.to_vec());
}
}