390 likes | 399 Views
Doubly-linked list library. typedef struct dllist { struct dllist *flink; struct dllist *blink; Jval val; } *Dllist;. Link to next node. Link to previous node. The node’s value. Next node. flink. Previous node. blink. val. Dllist library structure. Circular Doubly-linked
E N D
Doubly-linked list library. typedef struct dllist { struct dllist *flink; struct dllist *blink; Jval val; } *Dllist; Link to next node Link to previous node The node’s value Next node flink Previous node blink val
Dllist library structure • Circular • Doubly-linked • With a sentinel (header) node list flink blink val flink flink flink flink … blink blink blink blink val val val val
Creating a list: new_dllist() Dllist l; l = new_dllist(); l flink blink val
Augmenting a list: dll_append() Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); l flink flink blink blink val val.i=3
Augmenting a list: dll_append() Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); l flink flink flink blink blink blink val val.i=3 val.i=8
What will this print? Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); printf(“%d\n”, l->flink->val.i); l flink flink flink blink blink blink val val.i=3 val.i=8
What will this print? Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); printf(“%d\n”, l->flink->val.i); l flink flink flink 3 blink blink blink val val.i=3 val.i=8
Augmenting a list: dll_prepend() Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_prepend(l, new_jval_s(“Jim”)); l flink flink flink flink blink blink blink blink val val.s val.i=3 val.i=8 “Jim”
What will this print? Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_prepend(l, new_jval_s(“Jim”)); printf(“%d\n”, l->flink->val.i); l flink flink flink flink blink blink blink blink val val.s val.i=3 val.i=8 “Jim”
What will this print? Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_prepend(l, new_jval_s(“Jim”)); printf(“%d\n”, l->flink->val.i); 10864 (or something similar) l flink flink flink flink blink blink blink blink val val.s val.i=3 val.i=8 “Jim”
Augmenting a list: dll_insert_b() Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_insert_b(l->flink->flink, new_jval_s(“Jim”)); Inserts before a given node. l flink flink flink flink blink blink blink blink val val.i=3 val.s val.i=8 “Jim”
What will this do? Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_insert_b(l, new_jval_s(“Jim”); l flink flink flink blink blink blink val val.i=3 val.i=8
What will this do? Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_insert_b(l, new_jval_s(“Jim”); l flink flink flink flink blink blink blink blink val val.i=3 val.i=8 val.s “Jim”
Deleting: dll_delete_node() Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_insert_b(l, new_jval_s(“Jim”); dll_delete_node(l->blink); l flink flink flink flink before blink blink blink blink val val.i=3 val.i=8 val.s “Jim”
Deleting: dll_delete_node() Dllist l; l = new_dllist(); dll_append(l, new_jval_i(3)); dll_append(l, new_jval_i(8)); dll_insert_b(l, new_jval_s(“Jim”); dll_delete_node(l->blink); l flink flink flink after blink blink blink val val.i=3 val.i=8
Deleting: free_dllist() • Destroys a list • Including the sentinel node. • Frees all malloc’d nodes • Does not free jvals! IS is; Dllist l; l = new_dllist(); is = new_inputstruct(NULL); while(get_line(is) >= 0) { dll_prepend(l, new_jval_s(strdup(is->text1))); } free_dllist(l);
Handy macros (from dllist.h) #define dll_first(d) ((d)->flink) #define dll_next(d) ((d)->flink) #define dll_last(d) ((d)->blink) #define dll_prev(d) ((d)->blink) #define dll_nil(d) (d) l flink flink flink blink blink blink val val.i=3 val.i=8
Traversal macros: weird but useful! #define dll_traverse(ptr, list) \ for (ptr = (list)->flink; ptr != (list); ptr = ptr->flink) #define dll_rtraverse(ptr, list) \ for (ptr = (list)->blink; ptr != (list); ptr = ptr->blink) l flink flink flink blink blink blink val val.i=3 val.i=8
Two programs to reverse stdin: #include “fields.h” #include “dllist.h” main() { IS is; Dllist l; is = new_inputstruct(NULL); l = new_dllist(); while(get_line(is) >= 0) { dll_prepend(l, new_jval_s(strdup(is->text1))); } dll_traverse(tmp, l) { printf(“%s”, tmp->val.s); } } #1
Two programs to reverse stdin: #include “fields.h” #include “dllist.h” main() { IS is; Dllist l; is = new_inputstruct(NULL); l = new_dllist(); while(get_line(is) >= 0) { dll_append(l, new_jval_s(strdup(is->text1))); } dll_rtraverse(tmp, l) { printf(“%s”, tmp->val.s); } } #2
Implementation: new_dllist() Dllist new_dllist() { Dllist d; d = (Dllist) malloc (sizeof(struct dllist)); d->flink = d; d->blink = d; return d; } d flink blink val
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } e.g. before dll_insert_b(n, new_jval_i(10)); n flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } newnode dll_insert_b(n, new_jval_i(10)); flink blink n val flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } newnode dll_insert_b(n, new_jval_i(10)); flink blink n val.i=10 flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } newnode dll_insert_b(n, new_jval_i(10)); flink blink n val.i=10 flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } newnode dll_insert_b(n, new_jval_i(10)); flink blink n val.i=10 flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } newnode dll_insert_b(n, new_jval_i(10)); flink blink n val.i=10 flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } newnode dll_insert_b(n, new_jval_i(10)); flink blink n val.i=10 flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_insert_b() void dll_insert_b(Dllist node, Jval v) { Dllist newnode; newnode = (Dllist) malloc (sizeof(struct dllist)); newnode->val = v; newnode->flink = node; newnode->blink = node->blink; newnode->flink->blink = newnode; newnode->blink->flink = newnode; } dll_insert_b(n, new_jval_i(10)); n flink flink flink flink blink blink blink blink val.i=3 val.i=10 val.i=8 val.i=2
Implementation: dll_insert_a() void dll_insert_a(Dllist n, Jval val) { dll_insert_b(n->flink, val); } n flink flink flink blink blink blink val val.i=3 val.i=8
Implementation: dll_append() void dll_append(Dllist l, Jval val) { dll_insert_b(l, val); } l flink flink flink blink blink blink val val.i=3 val.i=8
Implementation: dll_prepend() void dll_prepend(Dllist l, Jval val) { dll_insert_a(l, val); } l flink flink flink blink blink blink val val.i=3 val.i=8
Implementation: dll_delete_node() void dll_delete_node(Dllist node) { node->flink->blink = node->blink; node->blink->flink = node->flink; free(node); } e.g. before dll_delete_node(n); n flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_delete_node() void dll_delete_node(Dllist node) { node->flink->blink = node->blink; node->blink->flink = node->flink; free(node); } dll_delete_node(n); n flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_delete_node() void dll_delete_node(Dllist node) { node->flink->blink = node->blink; node->blink->flink = node->flink; free(node); } dll_delete_node(n); n flink flink flink blink blink blink val.i=3 val.i=8 val.i=2
Implementation: dll_delete_node() void dll_delete_node(Dllist node) { node->flink->blink = node->blink; node->blink->flink = node->flink; free(node); } dll_delete_node(n); n flink flink blink blink val.i=3 val.i=2
Implementation: dll_delete_node() void dll_delete_node(Dllist node) { node->flink->blink = node->blink; node->blink->flink = node->flink; free(node); } dll_delete_node(n); n ? flink flink blink blink val.i=3 val.i=2
Implementation: free_dllist() void free_dllist(Dllist l) { while (!dll_empty(l)) { dll_delete_node(dll_first(l)); } free(l); } l flink flink flink blink blink blink val val.i=3 val.i=8
Implementation: dll_empty() int dll_empty(Dllist l) { return (l->flink == l); } l flink flink flink blink blink blink val val.i=3 val.i=8