C Everything
This is a C repository containing a curated set of generic data structures and algorithm.
link_list.c
Go to the documentation of this file.
1 
6 #include "link_list.h"
7 
8 void add_begin_sll(t_gen d,t_gen data);
9 void add_begin_dll(t_gen d,t_gen data);
10 void add_begin_scll(t_gen d,t_gen data);
11 void add_begin_dcll(t_gen d,t_gen data);
12 void add_begin_xor_dll(t_gen d,t_gen data);
13 
14 void add_end_sll(t_gen d,t_gen data);
15 void add_end_dll(t_gen d,t_gen data);
16 void add_end_scll(t_gen d,t_gen data);
17 void add_end_dcll(t_gen d,t_gen data);
18 void add_end_xor_dll(t_gen d,t_gen data);
19 
20 t_gen del_node_sll(t_gen d, t_gen data);
21 t_gen del_node_dll(t_gen d, t_gen data);
22 t_gen del_node_scll(t_gen d, t_gen data);
25 
26 t_gen del_node_sll_idx(t_gen d, int idx);
27 t_gen del_node_dll_idx(t_gen d, int idx);
28 t_gen del_node_scll_idx(t_gen d, int idx);
29 t_gen del_node_dcll_idx(t_gen d, int idx);
30 t_gen del_node_xor_idx(t_gen d, int idx);
31 
32 int linklist_length(t_gen d);
34 t_gen linklist_getnode(t_gen d, int idx);
35 
36 void linklist_print (t_gen d);
37 void linklist_print_info (t_gen d);
38 
39 void destroy_link_list (t_gen d);
40 
47 
48 t_gen xor(t_gen x, t_gen y);
49 
52 
55 
58 
61 
69 t_gen create_link_list (char *name, e_lltype type, t_dparams *prm)
70 {
71  t_linklist *l = (t_linklist*)get_mem(1, sizeof(t_linklist));
72 
73  // Initailze LL Params
74  l->name = name;
75  l->type = type;
76  l->count = 0;
77  l->tail = l->head = NULL;
78 
79  // Select Functions based on type of list
80  l->append = append[type];
81  l->add = add[type];
82  l->del = del[type];
83  l->del_idx = del_idx[type];
85  l->len = linklist_length;
86  l->find = linklist_find;
93  l->print = linklist_print;
96 
97  l->cmpr = prm->cmpr;
98  l->swap = prm->swap;
99  l->print_data = prm->print_data;
100  l->free = prm->free;
101 
102  return (t_gen)l;
103 }
104 
111 {
112  t_llnode *node = (t_llnode*)n;
113 
114  return node->data;
115 }
116 
123 void add_begin_sll(t_gen d, t_gen data)
124 {
125  t_linklist *l = (t_linklist*)d;
126  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
127 
128  // Create a node and assign data
129  node->data = data;
130 
131  // Link cur head to new node
132  node->nxt = l->head;
133 
134  // update tail
135  if (l->head == NULL) {
136  l->tail = node;
137  }
138  // Update head to new node
139  l->head = node;
140  l->count++;
141 }
142 
149 void add_begin_dll(t_gen d, t_gen data)
150 {
151  t_linklist *l = (t_linklist*)d;
152  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
153 
154  // Create a node and assign data
155  node->data = data;
156 
157  // Link cur head to new node
158  node->nxt = l->head;
159 
160  // ground head for head node
161  node->prv = NULL;
162 
163  // Update Prv node link if non empty list
164  if (l->head != NULL) {
165  l->head->prv = node;
166  } else {
167  l->tail = node;
168  }
169 
170  // Update head to new node
171  l->head = node;
172  l->count++;
173 }
174 
182 {
183  t_linklist *l = (t_linklist*)d;
184  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
185 
186  // Create a node and assign data
187  node->data = data;
188 
189  // Link cur head to new node
190  node->nxt = l->head;
191 
192  // Update head to new node
193  l->head = node;
194 
195  if (l->tail != NULL) {
196  // Circ Link tail to head
197  l->tail->nxt = l->head;
198  } else {
199  // List Empty update head & tail
200  l->tail = l->head;
201  }
202  l->count++;
203 }
204 
212 {
213  t_linklist *l = (t_linklist*)d;
214  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
215 
216  // Create a node and assign data
217  node->data = data;
218 
219  // Circ Link new node prv & nxt with tail and head respect
220  node->nxt = l->head;
221  node->prv = l->tail;
222 
223  if (l->tail != NULL) {
224  // Rvrs link cur head to new node(head)
225  l->head->prv = node;
226  l->head = node;
227  // Circ Link tail to head
228  l->tail->nxt = l->head;
229  } else {
230  // List Empty update head & tail
231  l->tail = l->head = node ;
232  }
233  l->count++;
234 }
235 
241 {
242  return (t_gen)((uintptr_t)(x) ^ (uintptr_t)(y));
243 }
244 
252 {
253  t_linklist *l = (t_linklist*)d;
254  t_llnode *node;
255 
256  // create node and store data
257  node = (t_llnode*)get_mem(1, sizeof(t_llnode));
258  node->data = data;
259  //node->nxt = l->head ^ NULL
260  node->nxt = xor(l->head ,NULL);
261 
262  if (l->head != NULL)
263  {
264  // In order to get the address of the next node, XOR it with `NULL`
265  //l->head->nxt = (l->head->nxt ^ NULL) ^ node;
266  l->head->nxt = xor(node, xor(l->head->nxt, NULL));
267  }
268 
269  // update tail
270  if (l->head == NULL) {
271  l->tail = node;
272  }
273  // Update head to new node
274  l->head = node;
275  l->count++;
276 
277 }
278 
285 void add_end_sll(t_gen d,t_gen data)
286 {
287  t_linklist *l = (t_linklist*)d;
288  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
289 
290  // Create a node and assign data
291  node->data = data;
292  node->nxt = NULL;
293 
294  if (l->head == NULL) {
295  // List Empty upadte head
296  l->head = node;
297  } else {
298  // Add new node as nxt of cur tail
299  l->tail->nxt = node;
300  }
301  // Add new node as tail
302  l->tail = node;
303  l->count++;
304 }
305 
312 void add_end_dll(t_gen d,t_gen data)
313 {
314  t_linklist *l = (t_linklist*)d;
315  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
316 
317  // Create a node and assign data
318  node->data = data;
319  node->prv = node->nxt = NULL;
320 
321  if (l->head == NULL) {
322  // List Empty upadte head
323  l->head = node;
324  } else {
325  // Rev link to cur tail
326  node->prv = l->tail;
327  // Add new node as nxt of cur tail
328  l->tail->nxt = node;
329  }
330  // Add new node as tail
331  l->tail = node;
332  l->count++;
333 }
334 
341 void add_end_scll(t_gen d,t_gen data)
342 {
343  t_linklist *l = (t_linklist*)d;
344  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
345 
346  // Create a node and assign data
347  node->data = data;
348  node->nxt = NULL;
349 
350  if (l->head == NULL) {
351  // List Empty upadte head
352  l->head = node;
353  } else {
354  // Add new node as nxt of cur tail
355  l->tail->nxt = node;
356  }
357  // Add new node as tail
358  l->tail = node;
359  // Circular link tail to head
360  l->tail->nxt = l->head;
361  l->count++;
362 }
363 
370 void add_end_dcll(t_gen d,t_gen data)
371 {
372  t_linklist *l = (t_linklist*)d;
373  t_llnode *node = (t_llnode*)get_mem(1, sizeof(t_llnode));
374 
375  // Create a node and assign data
376  node->data = data;
377  node->prv = node->nxt = NULL;
378 
379  if (l->head == NULL) {
380  // List Empty upadte head
381  l->head = node;
382  } else {
383  l->tail->nxt = node;
384  node->prv = l->tail;
385  }
386  // Add new node as tail
387  // Rev link head to new tail
388  l->head->prv = l->tail = node;
389  // Circular link tail to head
390  l->tail->nxt = l->head;
391  l->count++;
392 }
393 
401 {
402  t_linklist *l = (t_linklist*)d;
403  t_llnode *node;
404 
405  // Create a node and assign data
406  node = (t_llnode*)get_mem(1, sizeof(t_llnode));
407  node->data = data;
408 
409  // node->nxt = l->tail ^ NULL;
410  node->nxt = xor(l->tail, NULL);
411 
412  if (l->head == NULL) {
413  // List Empty upadte head
414  //l->head = (t_llnode *)XOR(node, l->head) ;
415  l->head = l->tail = node;
416  } else {
417  // Add new node as nxt of cur tail
418  //l->tail->nxt = (l->tail->nxt ^ NULL) ^ node;
419  l->tail->nxt = xor(node, xor(l->tail->nxt, NULL));
420  }
421  // Add new node as tail
422  l->tail = node;
423  l->count++;
424 }
425 
434 {
435  t_linklist *l = (t_linklist *)d;
436  t_llnode *cur = l->head, *prv;
437  t_gen tmp = NULL;
438  // empty list
439  if (l->head == NULL) {
440  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
441  return tmp;
442  }
443 
444  // Head node is to be deleted and new head is updated
445  if (l->cmpr(cur->data, data) == eEQUAL) {
446  l->head = cur->nxt;
447  cur->nxt = NULL;
448  tmp = cur->data;
449  free_mem(cur);
450  l->count--;
451  // Reset Tail to NULL if list empty
452  l->tail = l->head? l->tail : NULL;
453  return tmp;
454  }
455 
456  // Find the node to be deleted
457  while (l->cmpr(cur->data, data) != eEQUAL) {
458  prv = cur;
459  cur = cur->nxt;
460  // Node to be deleted not found
461  if (cur == NULL) {
462  LOG_INFO("LINK_LIST", "%s: No node found within the link list\n",l->name);
463  return tmp;
464  }
465  }
466 
467  // Unlink cur node and update link
468  prv->nxt = cur->nxt;
469  // If last node deleted update tail ref
470  if (prv->nxt == NULL) {
471  l->tail = prv;
472  }
473  l->count--;
474  // Free node
475  cur->nxt = NULL;
476  tmp = cur->data;
477  free_mem(cur);
478 
479  return tmp;
480 }
481 
482 
483 
492 {
493  t_linklist *l = (t_linklist *)d;
494  t_llnode *cur = l->head;
495  t_gen tmp = NULL;
496 
497  // empty list
498  if (l->head == NULL) {
499  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
500  return tmp;
501  }
502 
503  // Head node is to be deleted and new head is updated
504  if (l->cmpr(cur->data, data) == eEQUAL) {
505  l->head = cur->nxt;
506  if (l->head != NULL) {
507  l->head->prv = NULL;
508  }
509  l->count--;
510  // Reset Tail to NULL if list empty
511  l->tail = l->head? l->tail : NULL;
512  cur->nxt = cur->prv = NULL;
513  tmp = cur->data;
514  free_mem(cur);
515  return tmp;
516  }
517 
518  // Find the node to be deleted
519  while (l->cmpr(cur->data, data) != eEQUAL) {
520  cur = cur->nxt;
521  // Node to be deleted not found
522  if(cur == NULL) {
523  LOG_INFO("LINK_LIST", "%s: No node found within the link list\n",l->name);
524  return tmp;
525  }
526  }
527 
528  // Unlink cur node and update fwd link
529  cur->prv->nxt = cur->nxt;
530  if (cur->nxt == NULL) {
531  // If last node deleted update tail ref
532  l->tail = cur->prv;
533  } else {
534  // Preserve rev link
535  cur->nxt->prv = cur->prv;
536  }
537 
538  // Free node
539  l->count--;
540  cur->nxt = cur->prv = NULL;
541  tmp = cur->data;
542  free_mem(cur);
543 
544  return tmp;
545 }
546 
547 
548 
557 {
558  t_linklist *l = (t_linklist *)d;
559  t_llnode *cur = l->head, *prv;
560  t_gen tmp = NULL;
561 
562  // empty list
563  if (l->head == NULL) {
564  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
565  return tmp;
566  }
567 
568  // Head node is to be deleted and new head is updated
569  if (l->cmpr(cur->data, data) == eEQUAL) {
570  // Unlink cur node and update fwd link for tail
571  l->tail->nxt = l->head = cur->nxt;
572  l->count--;
573  // Reset Tail to NULL if list empty
574  if (l->count == 0) {
575  l->tail = l->head = NULL;
576  }
577  cur->nxt = NULL;
578  tmp = cur->data;
579  free_mem(cur);
580  return tmp;
581  }
582 
583  // Find the node to be deleted
584  while (l->cmpr(cur->data, data) != eEQUAL) {
585  prv = cur;
586  cur = cur->nxt;
587 
588  // Node to be deleted not found
589  if (cur == l->head) {
590  LOG_INFO("LINK_LIST", "%s: No node found within the link list\n",l->name);
591  return tmp;
592  }
593  }
594 
595  l->count--;
596  // Unlink cur node and update fwd link
597  prv->nxt = cur->nxt;
598  // If last node deleted update tail ref
599  if (prv->nxt == l->head) {
600  l->tail = prv;
601  }
602  // Free node
603  cur->nxt = NULL;
604  tmp = cur->data;
605  free_mem(cur);
606 
607  return tmp;
608 }
609 
610 
611 
620 {
621  t_linklist *l = (t_linklist *)d;
622  t_llnode *cur = l->head;
623  t_gen tmp;
624 
625  // empty list
626  if (l->head == NULL) {
627  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
628  return tmp;
629  }
630 
631  // Head node is to be deleted and new head is updated
632  if (l->cmpr(cur->data, data) == eEQUAL) {
633  l->head = cur->nxt;
634  // Unlink cur node and update fwd and rev link
635  l->head->prv = l->tail;
636  l->tail->nxt = l->head;
637  l->count--;
638  // Reset Tail to NULL if list empty
639  if (l->count == 0) {
640  l->tail = l->head = NULL;
641  }
642  cur->nxt = cur->prv = NULL;
643  tmp = cur->data;
644  free_mem(cur);
645  return tmp;
646  }
647 
648  // Find the node to be deleted
649  while (l->cmpr(cur->data, data) != eEQUAL) {
650  cur = cur->nxt;
651  if(cur == l->head) {
652  LOG_INFO("LINK_LIST", "%s: No node found within the link list\n",l->name);
653  return tmp;
654  }
655  }
656 
657 
658  // Unlink cur node and update fwd
659  cur->prv->nxt = cur->nxt;
660  if (cur->nxt == l->head) {
661  // If last node deleted update tail ref
662  l->head->prv = l->tail = cur->prv;
663  } else {
664  cur->nxt->prv = cur->prv;
665  }
666 
667  l->count--;
668  // Free node
669  cur->nxt = cur->prv = NULL;
670  tmp = cur->data;
671  free_mem(cur);
672  return tmp;
673 }
674 
682 {
683  t_linklist *l = (t_linklist *)d;
684  t_llnode *cur = l->head;
685  t_llnode *prev = NULL , *next = NULL;
686  t_gen tmp = NULL;
687 
688 
689  // empty list
690  if (l->head == NULL) {
691  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
692  return tmp;
693  }
694 
695  // Head node is to be deleted and new head is updated
696  if (l->cmpr(cur->data, data) == eEQUAL) {
697  // l->head = cur->nxt ^ prev;
698  l->head = xor(cur->nxt, prev);
699 
700  // update reverse link
701  // Reset Tail to NULL if list empty
702  if (l->head != NULL) {
703  l->head->nxt = xor(prev, xor(l->head->nxt, cur));
704  }
705  else {
706  l->tail = NULL;
707  }
708 
709  l->count--;
710  // Free node
711  tmp = cur->data;
712  cur->nxt = NULL;
713  free_mem(cur);
714 
715  return tmp;
716  }
717 
718  // Find the node to be deleted
719  while (l->cmpr(cur->data, data) != eEQUAL) {
720  //next = cur->nxt ^ prev;
721  next = xor(cur->nxt, prev);
722  // Node to be deleted not found
723  if(next == NULL) {
724  LOG_INFO("LINK_LIST", "%s: No node found within the link list\n",l->name);
725  return tmp;
726  }
727  prev = cur;
728  cur = next;
729  }
730 
731  // next = cur->nxt ^ prev;
732  next = xor(cur->nxt, prev);
733 
734  // prev->nxt = (prev->nxt ^ cur) ^ (next) ;
735  prev->nxt = xor(next, xor(prev->nxt, cur)) ;
736 
737  // Update tail when the last node is deleted
738  if (next == NULL) {
739  l->tail = prev;
740  }
741  else {
742  // next->nxt = (next->nxt ^ cur) ^ prev;
743  next->nxt = xor(prev, xor(next->nxt, cur));
744  }
745 
746  // free node
747  l->count --;
748  tmp = cur->data;
749  cur->nxt = NULL;
750  free_mem(cur);
751 
752  return tmp;
753 
754 }
755 
756 
765 {
766  t_linklist *l = (t_linklist *)d;
767  t_llnode *cur = l->head, *prv = NULL;
768  t_gen tmp = NULL;
769 
770  // empty list
771  if (l->head == NULL) {
772  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
773  return tmp;
774  }
775  // idx >count
776  if (idx >= l->count && idx < 0) {
777  LOG_WARN("LINK_LIST", "%d: Index out of bounds, number of nodes that exist = %d\n",idx, l->count);
778  return tmp;
779  }
780 
781  for(int i = 0; i < idx; i++) {
782  prv = cur;
783  cur = cur->nxt;
784  }
785  // Head node is to be deleted and new head is updated
786  if (idx == 0) {
787  l->head = cur->nxt;
788  // Reset Tail to NULL if list empty
789  l->tail = l->head? l->tail : NULL;
790  }
791 
792  else {
793  // Unlink cur node and update link
794  prv->nxt = cur->nxt;
795  // If last node deleted update tail ref
796  if (prv->nxt == NULL) {
797  l->tail = prv;
798  }
799  }
800  l->count--;
801  // Free node
802  cur->nxt = NULL;
803  tmp = cur->data;
804  free_mem(cur);
805 
806  return tmp;
807 }
808 
809 
810 
819 {
820  t_linklist *l = (t_linklist *)d;
821  t_llnode *cur = l->head;
822  t_gen tmp = NULL;
823 
824  // empty list
825  if (l->head == NULL) {
826  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
827  return tmp;
828  }
829 
830  // idx >list count
831  if (idx >= l->count && idx < 0) {
832  LOG_WARN("LINK_LIST", "%d: Index out of bounds, number of nodes that exist = %d\n",idx, l->count);
833  return tmp;
834  }
835 
836  for(int i = 0; i < idx ; i ++) {
837  cur = cur->nxt;
838  }
839  // Head node is to be deleted and new head is updated
840  if (idx == 0) {
841  l->head = cur->nxt;
842  if (l->head != NULL) {
843  l->head->prv = NULL;
844  }
845  // Reset Tail to NULL if list empty
846  l->tail = l->head? l->tail : NULL;
847  }
848 
849 
850  // Unlink cur node and update fwd link
851  else {
852  cur->prv->nxt = cur->nxt;
853  if (cur->nxt == NULL) {
854  // If last node deleted update tail ref
855  l->tail = cur->prv;
856  } else {
857  // Preserve rev link
858  cur->nxt->prv = cur->prv;
859  }
860  }
861 
862  // Free node
863  l->count--;
864  cur->nxt = cur->prv = NULL;
865  tmp = cur->data;
866  free_mem(cur);
867 
868  return tmp;
869 }
870 
871 
880 {
881  t_linklist *l = (t_linklist *)d;
882  t_llnode *cur = l->head, *prv;
883  t_gen tmp = NULL;
884 
885  // empty list
886  if (l->head == NULL) {
887  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
888  return tmp;
889  }
890  // idx >list count
891  if (idx >= l->count && idx < 0) {
892  LOG_WARN("LINK_LIST", "%d: Index out of bounds, number of nodes that exist = %d\n",idx, l->count);
893  return tmp;
894  }
895 
896  for(int i = 0; i < idx; i ++) {
897  prv = cur;
898  cur = cur->nxt;
899 
900  // Node to be deleted not found
901  if (cur == l->head) {
902  LOG_INFO("LINK_LIST", "%s: No node of index %d found within the link list\n",l->name, idx);
903  return tmp;
904  }
905  }
906 
907  // Head node is to be deleted and new head is updated
908  if (idx == 0) {
909  // Unlink cur node and update fwd link for tail
910  l->tail->nxt = l->head = cur->nxt;
911  l->count--;
912  // Reset Tail to NULL if list empty
913  if (l->count == 0) {
914  l->tail = l->head = NULL;
915  }
916  cur->nxt = NULL;
917  tmp = cur->data;
918  free_mem(cur);
919  return tmp;
920  }
921 
922  else {
923  // Unlink cur node and update fwd link
924  prv->nxt = cur->nxt;
925  // If last node deleted update tail ref
926  if (prv->nxt == l->head) {
927  l->tail = prv;
928  }
929  }
930 
931  // Free node
932  l->count--;
933  cur->nxt = NULL;
934  tmp = cur->data;
935  free_mem(cur);
936 
937  return tmp;
938 }
939 
948 {
949  t_linklist *l = (t_linklist *)d;
950  t_llnode *cur = l->head;
951  t_gen tmp;
952 
953  // empty list
954  if (l->head == NULL) {
955  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
956  return tmp;
957  }
958 
959  // idx > list count
960  if (idx >= l->count && idx < 0) {
961  LOG_WARN("LINK_LIST", "%d: Index out of bounds, number of nodes that exist = %d\n",idx, l->count);
962  return tmp;
963  }
964 
965  for(int i = 0; i < idx; i ++) {
966  cur = cur->nxt;
967  if(cur == l->head) {
968  LOG_INFO("LINK_LIST", "%s: No node of index %d found within the link list\n",l->name, idx);
969  return tmp;
970  }
971  }
972 
973  // Head node is to be deleted and new head is updated
974  if (idx == 0) {
975  l->head = cur->nxt;
976  // Unlink cur node and update fwd and rev link
977  l->head->prv = l->tail;
978  l->tail->nxt = l->head;
979  l->count--;
980  // Reset Tail to NULL if list empty
981  if (l->count == 0) {
982  l->tail = l->head = NULL;
983  }
984  cur->nxt = cur->prv = NULL;
985  tmp = cur->data;
986  free_mem(cur);
987 
988  return tmp;
989  }
990 
991  else {
992  // Unlink cur node and update fwd
993  cur->prv->nxt = cur->nxt;
994  if (cur->nxt == l->head) {
995  // If last node deleted update tail ref
996  l->head->prv = l->tail = cur->prv;
997  } else {
998  cur->nxt->prv = cur->prv;
999  }
1000  }
1001 
1002  l->count--;
1003  // Free node
1004  cur->nxt = cur->prv = NULL;
1005  tmp = cur->data;
1006  free_mem(cur);
1007 
1008  return tmp;
1009 
1010 }
1011 
1020 {
1021  t_linklist *l = (t_linklist *)d;
1022  t_llnode *cur = l->head, *prv = NULL, *next = NULL;
1023  t_gen tmp = NULL;
1024 
1025  // empty list
1026  if (l->head == NULL) {
1027  LOG_WARN("LINK_LIST", "%s: No nodes exist\n",l->name);
1028  return tmp;
1029  }
1030  // idx >count
1031  if (idx >= l->count && idx < 0) {
1032  LOG_WARN("LINK_LIST", "%d: Index out of bounds, number of nodes that exist = %d\n",idx, l->count);
1033  return tmp;
1034  }
1035 
1036 
1037  for(int i = 0; i < idx; i++) {
1038  prv = cur;
1039  cur = l->next_node(l, prv);
1040  }
1041 
1042  // delete for head node
1043  if (idx == 0) {
1044 
1045  // l->head = cur->nxt ^ prev;
1046  l->head = xor(cur->nxt, prv);
1047 
1048  // update reverse link
1049  // Reset Tail to NULL if list empty
1050  if (l->head != NULL) {
1051  l->head->nxt = xor(prv, xor(l->head->nxt, cur));
1052  }
1053  else {
1054  l->tail = NULL;
1055  }
1056 
1057  }
1058  // delete for all the other nodes apart from head
1059  else {
1060  // next = cur->nxt ^ prev;
1061  next = xor(cur->nxt, prv);
1062 
1063  // prev->nxt = (prev->nxt ^ cur) ^ (next) ;
1064  prv->nxt = xor(next, xor(prv->nxt, cur)) ;
1065 
1066  // Update tail when the last node is deleted
1067  if (next == NULL) {
1068  l->tail = prv;
1069  }
1070  else {
1071  // next->nxt = (next->nxt ^ cur) ^ prev;
1072  next->nxt = xor(prv, xor(next->nxt, cur));
1073  }
1074  }
1075  l->count--;
1076  // Free node
1077  tmp = cur->data;
1078  cur->nxt = NULL;
1079  free_mem(cur);
1080 
1081  return tmp;
1082 
1083 }
1084 
1085 
1092 {
1093  t_linklist *l = (t_linklist*)d;
1094 
1095  return l->count;
1096 }
1097 
1106 {
1107  t_linklist *l = (t_linklist*)d;
1108  t_llnode *ptr;
1109  int i;
1110 
1111  // return NULL for index out of bound
1112  if ((idx < 0) || (idx >= l->count)) {
1113  return NULL;
1114  }
1115  ptr = l->head_node(l);
1116 
1117  for (i = 0; i < idx; i++) {
1118  ptr = l->next_node(l, ptr);
1119  }
1120 
1121  return ptr;
1122 }
1123 
1131 {
1132  t_linklist *l = (t_linklist*)d;
1133  t_llnode *ptr, *end;
1134 
1135  ptr = l->head_node(l);
1136  // if empty list, return NULL
1137  if (ptr == NULL) {
1138  return NULL;
1139  }
1140 
1141  end = l->end_node(l);
1142 
1143  while (l->cmpr(ptr->data, data) != eEQUAL) {
1144  ptr = l->next_node(l, ptr);
1145 
1146  //reach end of the linked list and node not present, return NULL
1147  if (ptr == end) {
1148  return NULL;
1149  }
1150  }
1151 
1152  return ptr;
1153 }
1154 
1155 
1162 {
1163  t_linklist *l = (t_linklist*)d;
1164 
1165  return l->head;
1166 }
1167 
1174 {
1175  t_linklist *l = (t_linklist*)d;
1176 
1177  return l->tail;
1178 }
1179 
1186 {
1187  t_linklist *l = (t_linklist*)d;
1188  t_llnode *end = NULL;
1189 
1190  // Return end of link list depending on type of link list
1191  switch (l->type)
1192  {
1193  case eSINGLE_LINKLIST:
1194  case eDOUBLE_LINKLIST:
1195  end = NULL;
1196  break;
1199  end = l->head;
1200  break;
1201  case eXOR_LINKLIST:
1202  end = NULL;
1203  break;
1204  }
1205  return end;
1206 }
1207 
1218 {
1219  t_linklist *l = (t_linklist*)d;
1220  t_llnode *node = (t_llnode*)n, *next;
1221  static t_llnode *prev = NULL;
1222 
1223  // return node -> next except for xor list
1224  if (l->type != eXOR_LINKLIST) {
1225  return node->nxt;
1226  }
1227  // limitation for xor next node be it iterrates from head
1228  // meaning first call should pass head node addr
1229  // and next time next node and so on
1230  prev = (l->head == node)? NULL: prev;
1231  next = xor(node->nxt, prev);
1232  prev = node;
1233 
1234  return next;
1235 }
1236 
1247 {
1248  t_linklist *l = (t_linklist*)d;
1249  t_llnode *prev = NULL, *node = (t_llnode*)n;
1250  static t_llnode *next = NULL;
1251 
1252  // Return end of link list depending on type of link list
1253  switch (l->type)
1254  {
1255  case eSINGLE_LINKLIST:
1257  prev = NULL;
1258  break;
1259  case eDOUBLE_LINKLIST:
1261  prev = node->prv;
1262  break;
1263  case eXOR_LINKLIST:
1264  // XOR node previous work only on reverse traveersal
1265  // meaning first call should pass tail node addr
1266  // and next time the node before tail and so on
1267  next = (l->tail == node)? NULL: next;
1268  prev = xor(node->nxt, next);
1269  next = node;
1270  break;
1271  }
1272 
1273 
1274  return prev;
1275 }
1276 
1277 /* @brief
1278  * Util function to get type of list in string
1279  * @param type - Link list Type
1280  * @return String of link list type
1281 */
1283 {
1284  switch(type) {
1285  case eSINGLE_LINKLIST:
1286  return "SINGLE_LINKLIST";
1287  case eDOUBLE_LINKLIST:
1288  return "DOUBLE_LINKLIST";
1290  return "SINGLE_CIRCULAR_LINKLIST";
1292  return "DOUBLE_CIRCULAR_LINKLIST";
1293  case eXOR_LINKLIST:
1294  return "XOR_LINKLIST";
1295  }
1296 
1297  return "UNDEFINED";
1298 }
1299 
1306 {
1307  t_linklist *l = (t_linklist*)d;
1308  t_llnode *ptr, *end;
1309  int i;
1310 
1311  printf("%s : [", l->name);
1312 
1313  // get head ptr of ll
1314  ptr = l->head_node(l);
1315  // exit for Circ or non circ linked list
1316  end = l->end_node(l);
1317 
1318  while (ptr) {
1319  l->print_data(ptr->data);
1320  printf(" ");
1321  ptr = l->next_node(l, ptr);
1322 
1323  // exit if end of list
1324  if (ptr == end) {
1325  break;
1326  }
1327  }
1328  printf("]\n");
1329 
1330 }
1331 
1332 
1339 {
1340  t_linklist *l = (t_linklist*)d;
1341  t_llnode *ptr, *end;
1342  int i;
1343 
1344  printf("%s:%s {Head: %lx} {Tail: %lx} {count: %u}\n[",l->name,
1345  get_lltype_name(l->type),(long)l->head,(long)l->tail, l->count);
1346 
1347  // get head of link list
1348  ptr = l->head_node(l);
1349  // exit for Circ or non circ linked list
1350  end = l->end_node(l);
1351 
1352  while (ptr) {
1353  printf("[ %lx ", (long)ptr->prv);
1354  l->print_data(ptr->data);
1355  printf(" %lx]", (long)ptr->nxt);
1356 
1357  ptr = l->next_node(l, ptr);
1358  // exit if end of list
1359  if (ptr == end) {
1360  break;
1361  }
1362  }
1363  printf(" ]\n");
1364 
1365 }
1366 
1367 
1374 {
1375  t_linklist *l = (t_linklist*)d;
1376  t_llnode *tmp,*ptr,*end;
1377  int i;
1378 
1379  // delete all node in llist
1380  ptr = l->head_node(l);
1381 
1382  // exit for Circ or non circ linked list
1383  end = l->end_node(l);
1384 
1385  while (ptr) {
1386  tmp = ptr;
1387  ptr = l->next_node(l, ptr);
1388  l->count--;
1389  // free node
1390  tmp->nxt = tmp->prv = NULL;
1391  l->free(tmp->data, __FILE__, __LINE__);
1392  free_mem(tmp);
1393  if(ptr == end) {
1394  break;
1395  }
1396  }
1397 
1398  if (l->count != 0) {
1399  LOG_ERROR(l->name, "%d nodes remain\n", l->count);
1400  }
1401  // Reset count, head and tail ptrs
1402  l->tail = l->head = NULL;
1403 
1404  free_mem(l);
1405 }
1406 
1407 
#define LOG_INFO(mod, fmt, args...)
Definition: logger.h:19
#define LOG_ERROR(mod, fmt, args...)
Definition: logger.h:17
#define LOG_WARN(mod, fmt, args...)
Definition: logger.h:18
#define free_mem(mem_addr)
Definition: memory_manager.h:9
#define get_mem(nmemb, size)
Definition: memory_manager.h:8
data params struct defn
Definition: common.h:18
f_cmpr cmpr
Routine used for comparing two given elems of said type.
Definition: common.h:23
f_swap swap
Routine used for swaping two elemnts of goven data.
Definition: common.h:25
f_free free
Routine used for freeing elements of said data.
Definition: common.h:26
f_print print_data
Routine used for printing elem data.
Definition: common.h:33
Link list node definition.
Definition: link_list.h:19
t_gen data
Pointer to the data to be stored in link list.
Definition: link_list.h:20
struct llnode * prv
Pointer to prev node in list.
Definition: link_list.h:22
struct llnode * nxt
Pointer to next node in list.
Definition: link_list.h:21
void * t_gen
Base Data type used for all data structure and data elements.
Definition: typedefs.h:41
f_vgen2 f_ins
fn type of insert elem function
Definition: typedefs.h:58
f_genidx f_del_idx
fn type of get elem at idx function
Definition: typedefs.h:62
@ eEQUAL
Definition: typedefs.h:36
f_gen2 f_del
fn type of delete elem function
Definition: typedefs.h:59