scire
Sadh's C++ Impromptu Routines Ensemble
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
linkedlist.hpp
Go to the documentation of this file.
1 // scire/struct/linkedlist
2 
3 // Copyright (c) 2014, Khan 'Sadh' Mostafa (http:// nafSadh.com/Khan)
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying text at http:// www.boost.org/LICENSE_1_0.txt)
6 
7 /**
8  scire/struct/linkedlist.hpp
9 
10  scire Linked List implementations:
11  - SinglyList : Singly Linked List
12  - DoublyList : Doubly Linked List
13  - CircularList : Circular List
14 
15  other required scire files:
16  scire/struct/container.hpp
17 
18  author:
19  ~nafSadh
20  */
21 #ifndef SCIRE_struct_linkedlist_HPP
22 #define SCIRE_struct_linkedlist_HPP
23 
24 #include <unordered_map>
25 #include "container.hpp"
26 
27 namespace scire
28 {
29 
31 #define SCIRE_SinglyList_CLASS
32  /**
33  * A Singly Linked List class.
34  *
35  * Singly linked list contains a linear list of items. Each item points to it's
36  * next; the last item of the list points to nullptr. A head pointer points to
37  * the first item of the list.
38  */
39  template<typename Type, typename SzType = int>
40  class SinglyList
41  : public AContainer<Type, SzType>
42  {
43  public:
44  /** initialize a SinglyList object, with head pointing to nullptr */
45  SinglyList();
46 
47  /** finalize a SinglyList object by deleting all items from the list */
48  virtual ~SinglyList();
49 
50  /**
51  * Traverse each item of the list
52  * @param travfunc function to traverse each item of list with
53  */
54  void Traverse(void(*travfunc)(const Type&)) const;
55 
56  /**
57  * insert a new item in the list with passed item after location nodes
58  * @param item item to insert as new item in the list
59  * @param location location in the list where the new item to insert
60  * @return SzType location where item inserted
61  */
62  SzType Insert(Type item, SzType location = 0);
63 
64  /** remove the item at location
65  @return true on success */
66  bool RemoveAt(
67  SzType location = 0/**< index of item to remove */
68  );
69 
70  /** remove first item in the linked list that matches passed item.
71  @return true if found and removed */
72  bool Remove(
73  const Type& item/**< item to remove */
74  );
75 
76  // @implement Container
77  virtual SzType Size() const;
78 
79  // @implement Container
80  virtual bool Add(const Type& item)
81  {
82  return (this->Insert(item, 0) == 0);
83  }
84 
85  // @implement Container
86  virtual bool Deduce();
87 
88  // @implement Container
89  virtual Type Peek() const;
90 
91  protected:
92  /** represent an item node in Singly Linked List */
93  struct Node {
94  public:
95  Type item; /** item at this node */
96  Node* next; /** pointer to next item */
97 
98  Node(const Type& newitem, Node *nextNode)
99  : item(newitem), next(nextNode) {}
100  const Type& Item() const
101  {
102  return item;
103  }
104  };
105 
106  /** points to first item of the list */
108 
109  const Node* Head() const
110  {
111  return head;
112  }
113 
114  /** track count of items in the list */
115  SzType size;
116  // ------------------------------ //
117  // Some Utility Friend Functions //
118  // ---------------------------- //
119 
120  public:
121  /** iterate through the list and remove duplicate items (i.e. remove those
122  items that appear more than once)
123  @return number of duplicates detected in original list */
125  SinglyList<Type, SzType>& list /**< list to operate on*/
126  )
127  {
128  // trivial case: no dup in an list with less than 2 items
129  if (list.Size() < 2) return 0;
130 
131  // iterate over the list, insert each new item in hashmap and delete all
132  // detected duplicate items from list
133  SzType dupCount = 0;
134  unordered_map<Type, bool> map;
135  Node* cur = list.head;
136  map.insert({cur->item, true});
137 
138  while (cur->next != nullptr) {
139  if (map.find(cur->next->item) == map.end()) {
140  map.insert({cur->next->item, true});
141  cur = cur->next;
142  } else {
143  dupCount++;
144  list.size--;
145  Node* temp = cur->next;
146  cur->next = cur->next->next;
147  delete temp;
148  }
149  }
150  return dupCount;
151  }
152 
153  /** Return the kth to the last item. If the list has n items, return (n-k)th
154  item of the list. If k=0, then return last item. If k>=n then it is an error.
155  @return const ref to (n-k)the item */
156  friend const Type& KthToTheLast(
157  const SinglyList<Type, SzType>& list, /**< list ti operate on*/
158  SzType k /** k */
159  )
160  {
161  k++;
162  Node* runr = list.head;
163  while (runr != nullptr && k-- > 0) {
164  runr = runr->next;
165  }
166  if (k > 0) return NULL;
167  Node* cur = list.head;
168  while (runr != nullptr) {
169  cur = cur->next;
170  runr = runr->next;
171  }
172 
173  return (cur->Item());
174  }
175 
176  };
177 
178  template<typename Type, typename SzType>
179  SinglyList<Type,SzType>::SinglyList()
180  : head(0), size()
181  {
182  // empty ctor body, all init on initlist
183  }
184 
185  template<typename Type, typename SzType>
186  SinglyList<Type, SzType>::~SinglyList()
187  {
188  Node *node = this->head;
189 
190  // remove all nodes to avoid leak
191  while (node != nullptr) {
192  Node *next = node->next;
193  delete node;
194  node = next;
195  }
196  }
197 
198  template<typename Type, typename SzType>
199  void SinglyList<Type, SzType>::Traverse(void(*travfunc)(const Type&)) const
200  {
201  Node *node = this->head;
202 
203  while (node != nullptr) {
204  travfunc(node->item);
205  node = node->next;
206  }
207  }
208 
209 
210  template<typename Type, typename SzType>
211  SzType SinglyList<Type, SzType>::Insert(Type item, SzType location)
212  {
213  Node *node = new Node(item, nullptr);
214  // exception when new fails
215  if (nullptr == node) {
216  return -1;
217  }
218 
219  this->size++;
220 
221  // if list is empty or if insert to 0th location (at begining)
222  // point node->next to head and make head point to this new node
223  if (location <= 0 || this->head == nullptr) {
224  node->next = this->head;
225  this->head = node;
226  return 0;
227  }
228 
229  // if list is not empty and location is not at beginning
230  SzType i = 0;
231  Node *prev = this->head;
232  // Node *curr = this->head;
233  // while (i++ < location && curr != nullptr) {
234  while (i++ < location && prev->next != nullptr) {
235  prev = prev->next;
236  }
237  node->next = prev->next;
238  prev->next = node;
239 
240  return i;
241  }//<<Insert(Type,SzType)
242 
243 
244  // # operation: RemoveAt # //
245  template<typename Type, typename SzType>
246  bool SinglyList<Type, SzType>::RemoveAt(SzType location)
247  {
248  if (this->IsEmpty()) return false; // can't remove from empty list
249  if (location >= size) return false; // check loc in bound
250  if (location < 0) return false;
251 
252  // if location 0 then remove from head
253  if (location == 0) {
254  Node* tmphd = head; // node to delete
255  head = head->next; // move head to next node
256  size--; // bookkeeping count
257  delete tmphd; // free the node
258  return true; // success
259  }
260 
261  // removing from location other than head
262  SzType i = 0;
263  Node* cur = head; // put cursor at head
264  SzType prevLoc = location - 1;
265  // move cursor to previous node
266  while (++i < prevLoc) {
267  cur = cur->next;
268  }
269  Node* temp = cur->next; // node to delete
270  if (cur->next == nullptr)
271  return false; // this node shouldn't have been null
272  cur->next = cur->next->next; // relink prev node with next to next
273  size--; // bookkeeping count
274  delete temp; // free the node
275  return true; // success
276  }//<<RemoveAt(SzType)
277 
278 
279  // # opeartion : Remove # //
280  template<typename Type, typename SzType>
281  bool SinglyList<Type, SzType>::Remove(const Type& item)
282  {
283  if (this->IsEmpty()) return false;
284 
285  // remove from head
286  if (item == head->item) {
287  Node* tmphd = head;
288  head = head->next;
289  size--;
290  delete tmphd;
291  return true;
292  }
293 
294  Node* cur = head;
295  while (cur->next != nullptr && cur->next->item != item) {
296  cur = cur->next;
297  }
298  if (cur->next == nullptr) return false;
299  Node* temp = cur->next;
300  cur->next = cur->next->next;
301  size--;
302  delete temp;
303  return true;
304  }
305 
306  template<typename Type, typename SzType>
307  SzType SinglyList<Type, SzType>::Size() const
308  {
309  return this->size;
310  }
311 
312  template<typename Type, typename SzType>
313  bool SinglyList<Type, SzType>::Deduce()
314  {
315  if (this->IsEmpty()) return false;
316 
317  Node *node = this->head;
318  this->head = head->next;
319  this->size--;
320  delete node;
321 
322  return true;
323  }
324 
325  template<typename Type, typename SzType>
326  Type SinglyList<Type, SzType>::Peek() const
327  {
328  return this->head->item;
329  }
330 #endif// SCIRE_SinglyList_CLASS
331 }// scire namespace
332 #endif// SCIRE_struct_linkedlist_HPP
Node(const Type &newitem, Node *nextNode)
pointer to next item
Definition: linkedlist.hpp:98
bool Remove(const Type &item)
remove first item in the linked list that matches passed item.
Definition: linkedlist.hpp:281
const Node * Head() const
Definition: linkedlist.hpp:109
virtual SzType Size() const
number of elements contained in
Definition: linkedlist.hpp:307
SzType Insert(Type item, SzType location=0)
insert a new item in the list with passed item after location nodes
Definition: linkedlist.hpp:211
Node * head
points to first item of the list
Definition: linkedlist.hpp:107
Container Inferface.
Definition: container.hpp:40
scire/graph/gale_shapley.hpp
const Type & Item() const
Definition: linkedlist.hpp:100
void Traverse(void(*travfunc)(const Type &)) const
Traverse each item of the list.
Definition: linkedlist.hpp:199
SinglyList()
initialize a SinglyList object, with head pointing to nullptr
Definition: linkedlist.hpp:179
virtual ~SinglyList()
finalize a SinglyList object by deleting all items from the list
Definition: linkedlist.hpp:186
represent an item node in Singly Linked List
Definition: linkedlist.hpp:93
virtual Type Peek() const
peek into next element contained in
Definition: linkedlist.hpp:326
bool RemoveAt(SzType location=0)
remove the item at location
Definition: linkedlist.hpp:246
SzType size
track count of items in the list
Definition: linkedlist.hpp:115
virtual bool Add(const Type &item)
add an element
Definition: linkedlist.hpp:80
friend bool IsBST(const BinaryTree &tree, Type min, Type max)
Definition: tree.hpp:69
Node * next
item at this node
Definition: linkedlist.hpp:96
virtual bool Deduce()
deduce one element
Definition: linkedlist.hpp:313
A Singly Linked List class.
Definition: linkedlist.hpp:40