self referential structures
play

Self-referential Structures A basic data type (building block) for - PDF document

4/8/14 Self-referential Structures A basic data type (building block) for complex data structures such as trees and linked lists. Linked List Structure tags (i.e. tnode , node ) are required for self-referential structure


  1. 4/8/14 ¡ Self-referential Structures • A basic data type (building block) for complex data structures such as trees and linked lists. Linked List • Structure tags (i.e. tnode , node ) are required for self-referential structure declarations. typedef struct tnode typedef struct node { { Based on slides from K. N. King and Dianna Xu int x; int x; struct tnode *left; struct node *next; struct tnode *right; } Listnode; Bryn Mawr College } Treenode; CS246 Programming Paradigm Linked Lists Singly and Doubly Linked Lists • A linked list stores a lists of items ( struct s). • A singly linked list has each struct containing only one pointer to the next. • Linked lists are typically unbounded, that is, they can grow infinitely. • A doubly linked list has each struct containing both a pointer to the previous as well as the next • An array is a single consecutive piece of memory, a struct in the list. linked list is made of many pieces. • A linked list offers quick insertion, deletion and reordering of the items. single double head tail head tail • The last node in the list contains a null pointer. • No “ random access ” capability of an array. NULL NULL NULL struct node makenode Node *makenode (int x) { struct node { Node *new; int num; if ( (new = (Node *) malloc( sizeof(Node) ) )!= NULL) { struct node *next; new->num = x; //(*new).num = x; }; //scanf("%d", &new->num); An scanf example new -> next = NULL; typedef struct node Node; } Node *head = NULL; //the list is initially empty else { Node *tail = NULL; printf("Out of memory!\n"); exit(0); } return new; } 1 ¡

  2. 4/8/14 ¡ append delete void delete (Node *p) { void append (Node *p) { Node *tmp, *prev; if ((p == head) && (p == tail)) if (head == NULL) { head = tail = NULL; head = p; else if (p == head) tail = p; head = p->next; } else { else { for(tmp=head, prev=NULL; tmp!=p; prev=tmp, tmp=tmp->next); tail->next = p; if (p == tail) tail = p; tail = prev; } prev->next = p->next; } } free(p); } insert_after print/search /* insert a node p after p2 */ void print() { void insert_after (Node *p, Node *p2) { Node *tmp; p->next = p2->next; for (tmp = head; tmp != NULL; tmp = tmp->next) printf("%d ", tmp->num); if (p2 == tail) printf("\n"); tail = p; } Node *search(int x) { p2->next = p; Node *tmp; } for (tmp = head; tmp != NULL; tmp = tmp->next) if (tmp->num == x) return tmp; return NULL; } main clear int main() { void clear() { Node *tmp; Node *tmp, *tmp2; int i; for (tmp = head; tmp != NULL; tmp = tmp2) { for (i = 0; i < 10; i++) { tmp2 = tmp->next; tmp = makenode(i); free(tmp); append(tmp); } } head = tail = NULL; print(); } tmp = makenode(9); insert_after(tmp, head->next->next); • Note that this only works if structure Node does delete(head->next); not contain any other pointers to memory print(); } 2 ¡

  3. 4/8/14 ¡ General Purpose Linked Lists General Purpose makenode • void * Lnode *makenode (void *data) { Lnode *new = NULL; • Generic pointer – just a memory address if ((new = (Lnode *) malloc(Lnode)) != NULL) { • Can be casted to any type new->prev = NULL; new->next = NULL; struct llist_node { new->data = data; void *data; struct llist_node *prev; } struct llist_node *next; return new; }; } typedef struct llist_node Lnode; Avoid Memory Leaks Shallow and Deep Copy • There are two ways to make a copy of a linked list • Whenever dynamically allocated storages are in • Shallow copy: use, memory leaks are plentiful o The new list consist of duplicated pointers only • The problem is more evident when complicated data structures are used t1 h1 o Mixing: list of trees, trees of lists, etc o Nesting: list of lists of lists t2 h2 • Deep copy: • When implementing complex data structures, plan o The new list consist of duplicated data as well as pointers your clear / release functions very carefully Pointers to Pointers • A variable can be modified by a function if and only if it is passed by reference/pointer. • If the variable to be modified is a pointer itself, one must pass a pointer to pointer, i.e. one must always add an extra level of referencing. int make_node(Node **new) { *new=(Node *)malloc(sizeof(Node)); if (*new != NULL) return 1; else return 0; } 3 ¡

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend