absence_thelab

view src/common/linkedlist.h @ 0:1cffe3409164

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Oct 2014 01:46:07 +0300
parents
children
line source
1 #ifndef _LINKEDLIST_H_
2 #define _LINKEDLIST_H_
4 template <class T>
5 struct ListNode {
6 T data;
7 ListNode<T> *next, *prev;
8 };
11 template <class T>
12 class LinkedList {
13 private:
14 ListNode<T> *head, *tail;
15 int size;
17 public:
19 LinkedList();
20 ~LinkedList();
22 inline ListNode<T> *Begin();
23 inline ListNode<T> *End();
25 void PushBack(ListNode<T> *node);
26 void PushBack(T data);
28 void Insert(ListNode<T> *pos, ListNode<T> *node);
29 void Insert(ListNode<T> *pos, T data);
31 void Remove(ListNode<T> *node);
32 ListNode<T> *Erase(ListNode<T> *node);
34 ListNode<T> *Find(T key);
36 int CountNodes();
37 inline int Size() const;
39 void operator =(LinkedList &rhs);
40 };
43 /////////// implementation //////////
44 template <class T>
45 LinkedList<T>::LinkedList() {
46 head = tail = 0;
47 size = 0;
48 }
51 template <class T>
52 LinkedList<T>::~LinkedList() {
54 while(head) {
55 Erase(head);
56 }
57 }
59 template <class T>
60 ListNode<T> *LinkedList<T>::Begin() {
61 return head;
62 }
64 template <class T>
65 ListNode<T> *LinkedList<T>::End() {
66 return tail;
67 }
69 template <class T>
70 void LinkedList<T>::PushBack(ListNode<T> *node) {
72 if(!head) { // empty list
73 head = tail = node;
74 node->next = node->prev = 0;
75 } else {
76 tail->next = node;
77 node->prev = tail;
78 tail = node;
79 node->next = 0;
80 }
82 size++;
83 }
85 template <class T>
86 void LinkedList<T>::PushBack(T data) {
88 ListNode<T> *node = new ListNode<T>;
89 node->data = data;
91 if(!head) { // empty list
92 head = tail = node;
93 node->next = node->prev = 0;
94 } else {
95 tail->next = node;
96 node->prev = tail;
97 tail = node;
98 node->next = 0;
99 }
101 size++;
102 }
104 template <class T>
105 void LinkedList<T>::Insert(ListNode<T> *pos, ListNode<T> *node) {
107 if(!head) {
108 head = tail = node;
109 node->next = node->prev = 0;
110 } else {
111 node->prev = pos->prev;
112 pos->prev = node;
113 node->next = pos;
114 if(head == pos) head = node; else node->prev->next = node;
115 }
117 size++;
118 }
120 template <class T>
121 void LinkedList<T>::Insert(ListNode<T> *pos, T data) {
123 ListNode<T> *node = new ListNode<T>;
124 node->data = data;
126 if(!head) {
127 head = tail = node;
128 node->next = node->prev = 0;
129 } else {
130 node->prev = pos->prev;
131 pos->prev = node;
132 node->next = pos;
133 if(head == pos) head = node; else node->prev->next = node;
134 }
136 size++;
137 }
139 template <class T>
140 void LinkedList<T>::Remove(ListNode<T> *node) {
142 if(!node) return; // e.g. Remove(head) on an empty list
144 if(node->prev) {
145 node->prev->next = node->next;
146 } else {
147 head = node->next;
148 }
150 if(node->next) {
151 node->next->prev = node->prev;
152 } else {
153 tail = node->prev;
154 }
156 size--;
157 }
159 template <class T>
160 ListNode<T> *LinkedList<T>::Erase(ListNode<T> *node) {
162 if(!node) return 0; // e.g. Erase(head) on an empty list
164 if(node->prev) {
165 node->prev->next = node->next;
166 } else {
167 head = node->next;
168 }
170 if(node->next) {
171 node->next->prev = node->prev;
172 } else {
173 tail = node->prev;
174 }
176 ListNode<T> *destr = node;
177 node = node->next;
179 delete destr;
181 size--;
183 return node;
184 }
186 template <class T>
187 ListNode<T> *LinkedList<T>::Find(T key) {
189 ListNode<T> *iter = head;
190 while(iter) {
191 if(iter->data == key) return iter;
192 iter = iter->next;
193 }
195 return 0; // null pointer if not found
196 }
198 template <class T>
199 int LinkedList<T>::CountNodes() {
201 size = 0;
203 ListNode<T> *iter = head;
204 while(iter) {
205 size++;
206 iter = iter->next;
207 }
209 return size;
210 }
212 template <class T>
213 int LinkedList<T>::Size() const {
214 return size;
215 }
218 template <class T>
219 void LinkedList<T>::operator =(LinkedList<T> &rhs) {
221 ListNode<T> *src = rhs.Begin();
222 while(src) {
223 PushBack(src->data);
224 src = src->next;
225 }
226 }
229 #endif // _LINKEDLIST_H_