-
Notifications
You must be signed in to change notification settings - Fork 8
/
linkedlist.oc
122 lines (103 loc) · 2.34 KB
/
linkedlist.oc
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
//! A doubly linked list implementation.
import std::mem
struct Node<T> {
value: T
next: &Node<T>
prev: &Node<T>
}
def Node::new(val: T, next: &Node<T> = null, prev: &Node<T> = null): &Node<T> {
let node = mem::alloc<Node<T>>()
node.value = val
node.next = next
node.prev = prev
return node
}
struct LinkedList<T> {
head: &Node<T>
tail: &Node<T>
size: u32
}
def LinkedList::new(): &LinkedList<T> {
let ll = mem::alloc<LinkedList<T>>()
ll.head = null
ll.tail = null
ll.size = 0
return ll
}
def LinkedList::push_front(&this, val: T): &Node<T> {
let node = Node<T>::new(val, .head)
if .head != null {
.head.prev = node
}
.head = node
if .tail == null {
.tail = node
}
.size += 1
return node
}
def LinkedList::push(&this, val: T): &Node<T> {
let node = Node<T>::new(val, null, .tail)
if .tail != null {
.tail.next = node
}
.tail = node
if .head == null {
.head = node
}
.size += 1
return node
}
def LinkedList::remove_node(&this, node: &Node<T>) {
if node.prev != null {
node.prev.next = node.next
} else {
.head = node.next
}
if node.next != null {
node.next.prev = node.prev
} else {
.tail = node.prev
}
.size -= 1
mem::free(node)
}
def LinkedList::pop_front(&this): T {
assert .head != null, "Empty list in LinkedList::pop_front"
let node = .head
let val = node.value
.remove_node(node)
return val
}
def LinkedList::pop(&this): T {
assert .tail != null, "Empty list in LinkedList::pop"
let node = .tail
let val = node.value
.remove_node(node)
return val
}
def LinkedList::free(&this) {
let cur = .head
while cur? {
let next = cur.next
.remove_node(cur)
cur = next
}
mem::free(this)
}
def LinkedList::is_empty(&this): bool => .head == null
def LinkedList::iter(&this): Iterator<T> => Iterator<T>(.head, forward: true)
def LinkedList::iter_rev(&this): Iterator<T> => Iterator<T>(.head, forward: false)
struct Iterator<T> {
node: &Node<T>
forward: bool
}
def Iterator::has_value(&this): bool => .node?
def Iterator::next(&this) {
if .forward {
.node = .node.next
} else {
.node = .node.prev
}
}
def Iterator::cur(&this): T => .node.value