-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnodes.rs
129 lines (116 loc) · 3.95 KB
/
nodes.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::rc::{Rc, Weak};
use std::cell::RefCell;
// Trait for objects that contain a reference to the head of a linked list
pub trait HasHead
where Self: Sized {
type Element: Node;
fn get_head(&self) -> Option<Rc<RefCell<Self::Element>>>;
fn set_head(&mut self, new_head: Option<Rc<RefCell<Self::Element>>>);
fn push(&mut self, node: Rc<RefCell<Self::Element>>) {
match self.get_head() {
None => {
node.borrow_mut().set_next(None);
node.borrow_mut().set_prev(None);
self.set_head(Some(node));
}
Some(ref head) => {
head.borrow_mut().set_prev(Some(Rc::downgrade(&node)));
node.borrow_mut().set_next(Some(Rc::clone(head)));
node.borrow_mut().set_prev(None);
self.set_head(Some(node));
}
}
}
fn pop_head(&mut self) -> Option<Rc<RefCell<Self::Element>>> {
if self.get_head().is_none() {None}
else {
let head = self.get_head().unwrap();
match head.borrow().get_next() {
None => {
self.set_head(None);
}
Some(ref new_head) => {
new_head.borrow_mut().set_prev(None);
self.set_head(Some(Rc::clone(new_head)));
}
}
head.borrow_mut().set_next(None);
Some(Rc::clone(&head))
}
}
fn reduce<U, F>(&self, f: F, initial: U) -> U
where F: Fn(U, Rc<RefCell<Self::Element>>) -> U {
match self.get_head() {
None => {initial}
Some(ref head) => {
let out = f(initial, Rc::clone(head));
head.borrow().reduce_forward(f, out)
}
}
}
}
// Trait for objects that are nodes in a linked list
pub trait Node
where Self: Sized {
fn get_next(&self) -> Option<Rc<RefCell<Self>>>;
fn set_next(&mut self, new_next: Option<Rc<RefCell<Self>>>);
fn get_prev(&self) -> Option<Weak<RefCell<Self>>>;
fn set_prev(&mut self, new_prev: Option<Weak<RefCell<Self>>>);
fn is_head(&self) -> bool {
self.get_prev().is_none()
}
fn is_only_child(&self) -> bool {
self.get_prev().is_none() && self.get_next().is_none()
}
// Fold left from this node
fn reduce_forward<U, F>(&self, f: F, out: U) -> U
where F: Fn(U, Rc<RefCell<Self>>) -> U {
match self.get_next() {
None => {out}
Some(ref next) => {
let out = f(out, Rc::clone(next));
next.borrow().reduce_forward(f, out)
}
}
}
fn remove(&mut self) {
match self.get_next() {
None => {}
Some(ref next) => {
match self.get_prev() {
None => {next.borrow_mut().set_prev(None);}
Some(ref prev) => {
next.borrow_mut().set_prev(Some(
Rc::downgrade(&Rc::clone(&prev.upgrade().unwrap()))
));
}
}
}
}
match self.get_prev() {
None => {}
Some(ref prev) => {
let prev = prev.upgrade().unwrap();
match self.get_next() {
None => {prev.borrow_mut().set_next(None);}
Some(ref next) => {
prev.borrow_mut().set_next(Some(Rc::clone(next)));
}
}
}
}
self.set_next(None);
self.set_prev(None);
}
// Get the depth from this node to the list head
fn get_depth_from_node(&self, node: Rc<RefCell<Self>>, depth: usize) -> usize {
match node.borrow().get_prev() {
Some(ref prev) => {
self.get_depth_from_node(prev.upgrade().unwrap(), depth + 1)
}
None => {
depth
}
}
}
}