1 / 76

Chapter 4. LISTS

Chapter 4. LISTS. Linked List. A linked list is a non-sequential collection of data items. For every data item in the linked list, there is an associated pointer that would give the memory location of the next data item in the list.

ima
Download Presentation

Chapter 4. LISTS

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 4. LISTS

  2. Linked List • A linked list is a non-sequential collection of data items. • For every data item in the linked list, there is an associated pointer that would give the memory location of the next data item in the list. • The data items in the linked list are not in consecutive memory locations. • Accessing of these items is easier as each data item contained within itself the address of next data item.

  3. Pros & Cons • Linked lists are dynamic data structures: grow or shrink • Efficient memory utilization: memory is allocated when required. • Insertion and deletions are easier & efficient: provide flexibility in inserting a data item at specified position & deletion of a data item. • More Memory: if the number of fields are more. • Access to an arbitrary data item is cumbersome & time consuming.

  4. Components of Linked List • Linked list is a non-sequential collection of a data items called nodes. • Each node in a linked list contains two fields. • Data field • Link field • Data field contains an actual value to be stored. • Link field contains the address of the next data item(node). • The address used to access a particular node is a pointer. • The link field of the last node contains zero rather than a valid address. • It is a null pointer & indicates the end of the list.

  5. Representation of a linked list • Physical View: • Logical View: struct node { int data; struct node *link; } • The first one is an integer data item & second one is link pointer to the next node of same type. • Such structures are called self-referential structures. Data Link

  6. ptr bat cat sat vat NULL Singly Linked Lists • compose of data part and link part • link part contains address of the next element in a list • non-sequential representations • size of the list is not predefined • dynamic storage allocation and deallocation

  7. ptr bat cat sat vat NULL mat Singly Linked Lists • To insert the word mat between cat and sat 1) get a currently unused node (paddr) 2) set paddr’s data to mat 3) set paddr’s link to point to the address found in the link of the node cat 4) set the link of the node cat to point to paddr

  8. ptr bat cat mat sat vat NULL Singly Linked Lists • To delete mat from the list 1) find the element that immediately precedes mat, which is cat 2) set its link to point to mat’s link cat->link=mat->link free(mat);

  9. Singly Linked Lists • Ex 4.1 [list of words ending in at] • define a node structure for the list • data field: character array • link field: pointer to the next node • self-referential structure typedef struct list_node *list_ptr; typedef struct list_node { char data[4]; list_ptr link; }; list_ptr ptr = NULL;

  10. Representing Chains in C • A mechanism for defining a node’s structure. • A way to create new nodes when we need them. (malloc) • A way to remove nodes that we no longer need. (free)

  11. b a t \0 Singly Linked Lists • Create a new node for our list then place the word bat into our list ptr=(list_ptr)malloc(sizeof(list_node)); strcpy(ptr->data,”bat”); ptr->link=NULL; address of first node ptr->data ptr->link NULL ptr

  12. ptr 10 20 NULL Singly Linked Lists • Ex 4.2 [two-node linked list] • create a linked list of integers typedef struct list_node *list_ptr; typedef struct list_node { int data; list_ptr link; }; list_ptr ptr = NULL;

  13. Singly Linked Lists list_ptr create2() { list_ptr first, second; first = (list_ptr)malloc(sizeof(list_node)); second = (list_ptr)malloc(sizeof(list_node)); second->link=NULL; second->data=20; first->data=10; first->link=second; return first; }

  14. 10 20 NULL 50 Singly Linked Lists • Ex 4.3 [list insertion] • determine if we have used all available memory: IS_FULL #define IS_FULL(ptr) (!(ptr)) • Function call: insert(&ptr, node); ptr node temp

  15. Singly Linked Lists void insert (list_ptr *pptr,list_ptr node) { list_ptr temp; temp=(list_ptr)malloc(sizeof(list_node)); if(IS_FULL(temp)) { fprintf(stderr,”The momory is full\n”); exit(1); } temp->data=50; if (*pptr) { temp->link = node->link; node->link = temp; } else { temp->link = NULL; *pptr = temp; } }

  16. ptr node trail = NULL ptr 10 50 20 50 20 NULL NULL (a) before deletion (b) after deletion 10 50 20 10 20 NULL NULL Singly Linked Lists • Ex 4.4 [list deletion] • ptr: point to the start of list • node: point to the node to be deleted • trail: point to the node that precedes node to be deleted delete(&ptr,NULL,ptr); delete(&ptr,ptr,ptr->link); ptr trail node ptr (a) before deletion (b) after deletion

  17. Singly Linked Lists void delete(list_ptr *pptr, list_ptr trail, list_ptr node) { if (trail) trail->link = node->link; else *pptr = (*pptr)->link; free(node); } • delete(&ptr,NULL,ptr); delete(&ptr,ptr,ptr->link); • Ex 4.5 [printing out a list] void print_list(list_ptr ptr) { printf(“The list contains: “); for(; ptr; ptr = ptr->link) printf(“%4d”, ptr->data); printf(“\n”); }

  18. top element link ······ NULL front rear element link ······ NULL Dynamically Linked Stacks And Queues #define MAX_STACKS 10 /* n=MAX_STACKS=10 */ typedef struct { int key; /* other fields here */ } element; typedef struct stack *stack_ptr; typedef struct stack { element item; stack_ptr link; }; stack_ptr top[MAX_STACKS]; (a) linked stack (b) linked queue

  19. top[0] element link key ······ NULL top[MAX_STACKS-1] ······ NULL Dynamically Linked Stacks And Queues · · · initial condition for n stacks top[i] = NULL, 0 ≤ i < MAX_STACKS boundary conditions top[i]==NULL iff the ith stack is empty IS_FULL(temp) iff the memory is full

  20. PUSH PUSH(Node *top) { NODE *new_node; int item; new_node = allocate_node(); new_node->num = item; new_node->ptr=top; top=new_node; return(top); }

  21. Dynamically Linked Stacks And Queues • Add to a linked stack void push(stack_ptr *ptop, element item) { stack_ptr temp = (stack_ptr)malloc(sizeof (stack)); if(IS_FULL(temp)) { fprintf(stderr,”The memory is full\n”); exit(1); } temp->item=item; temp->link=*ptop; *ptop = temp; } • #define IS_FULL(ptr) (!(ptr)) • push(&top[stack_no], item);

  22. Pop POP(NODE *top) { NODE *temp; if(top==NULL) { printf(“stack is empty\n”); return; } else { printf(“Deleted element is %d”,top->num); temp=top->ptr; free(top); top=temp; } }

  23. Dynamically Linked Stacks And Queues • Delete from a linked stack element pop(stack_ptr *ptop) { stack_ptr temp = *ptop; element item; if(IS_EMPTY(temp)) { fprintf(stderr,”The stack is empty\n”); exit(1); } item=temp->item; *ptop=temp->link; free(temp); return item; } • #define IS_EMPTY(ptr) (!(ptr)) • item=pop(&top[stack_no]);

  24. front rear element link ······ NULL Dynamically Linked Stacks And Queues #define MAX_QUEUES 10 /* m=MAX_QUEUES=10 */ typedef struct queue *queue_ptr; typedef struct queue { element item; queue_ptr link; }; queue_ptr front[MAX_QUEUES],rear[MAX_QUEUES]; (b) linked queue

  25. front[0] rear[0] element link key ······ NULL front[MAX_QUEUES-1] rear[MAX_QUEUES-1] ······ NULL Dynamically Linked Stacks And Queues · · · initial conditon for n queues front[i]=NULL, 0 £i < MAX_QUEUES boundary conditions front[i]==NULL iff the ith queue is empty IS_FULL(temp) iff the memory is full

  26. Dynamically Linked Stacks And Queues • Add to the rear of a linked queue void addq(queue_ptr *pfront, queue_ptr *prear, element item) { queue_ptr temp = (queue_ptr)malloc(sizeof(queue)); if(IS_FULL(temp)) { fprintf(stderr,”The memory is full\n”); exit(1); } temp->item=item; temp->link=NULL; if (*pfront) (*prear)->link=temp; else *pfront = temp; *prear = temp; } • addq(&front[queue_no], &rear[queue_no], item);

  27. Dynamically Linked Stacks And Queues • Delete from the front of a linked queue element deleteq(queue_ptr *pfront) { queue_ptr temp=*pfront; element item; if (IS_EMPTY(*pfront)) { fprintf(stderr,”The queue is empty\n”); exit(1); } item=temp->item; *pfront=temp->link; free(temp); return item; } • item=deleteq(&front[queue_no]); • comparison: array vs. linked list

  28. coef expon link a 3 14 2 8 1 0 NULL b 8 14 -3 10 10 6 NULL Polynomials • Representing polynomials as singly linked lists • A(x) = am-1xem-1 + ··· + a0xe0 typedef struct poly_node *poly_ptr; typedef struct poly_node { int coef; int expon; poly_ptr link; }; poly_ptr a,b,d; poly_node a = 3x14 + 2x8 + 1 b = 8x14 - 3x10 + 10x6

  29. To add two polynomials. • If the exponents of the two terms are equal we add two coefficients and create a new term for the result. • Move the pointers to the next nodes. • If the exp of the current term in a is less than the exp of the current term in b then create a duplicate of b. • Attach this term to the result called d & advance the ptr. • Similar action on a if a->expon > b->expon.

  30. 3 14 2 8 1 0 NULL a 8 14 -3 10 10 6 NULL b 11 14 NULL d rear Polynomials • Adding polynomials • (a) a->expon == b->expon

  31. 3 14 2 8 1 0 NULL a 8 14 -3 10 10 6 NULL b 11 14 -3 10 NULL d rear Polynomials • (b) a->expon < b->expon

  32. 3 14 2 8 1 0 NULL a 8 14 -3 10 10 6 NULL b 11 14 -3 10 2 8 NULL d rear Polynomials • (c) a->expon > b->expon

  33. 3 14 2 8 1 0 NULL a 8 14 -3 10 10 6 NULL b 11 14 -3 10 2 8 d 10 6 NULL rear Polynomials • (d) a->expon < b->expon

  34. 3 14 2 8 1 0 NULL a 8 14 -3 10 10 6 NULL b 11 14 -3 10 2 8 d 10 6 1 0 NULL rear Polynomials • (e) b == NULL;

  35. Polynomials poly_ptr padd(poly_ptr a,poly_ptr b) { poly_ptr front,rear,temp; int sum; rear=(poly_ptr)malloc(sizeof(poly_node)); if(IS_FULL(rear)) { fprintf(stderr,”The memory is full\n”); exit(1);} front = rear; while(a && b) switch(COMPARE(a->expon,b->expon)) { case -1: /* a->expon < b->expon */ attach(b->coef,b->expon,&rear); b = b->link; break; case 0: /* a->expon = b->expon */ sum = a->coef + b->coef; if(sum) attach(sum,a->expon,&rear); a = a->link; b = b->link; break; case 1: /* a->expon > b->expon */ attach(a->coef,a->expon,&rear); a = a->link; }

  36. Polynomials poly_ptr padd(poly_ptr a,poly_ptr b) { · · · (continued from the previous slide) for(; a; a=a->link) attach(a->coef,a->expon,&rear); for(; b; b=b->link) attach(b->coef,b->expon,&rear); rear->link = NULL; temp=front; front=front->link; free(temp); return front; }

  37. Polynomials • Function attach() to create a new node and append it to the end of d void attach(float coe, int exp, poly_ptr *pptr) { poly_ptr temp; temp=(poly_ptr)malloc(sizeof(poly_node)); if(IS_FULL(temp)) { fprintf(stderr,”The memory is full\n”); exit(1); } temp->coef = coe; temp->expon = exp; (*pptr)->link = temp; *pptr=temp; }

  38. Polynomials • Analysis of padd where • m, n : number of terms in each polynomial • coefficient additions: • O(min{m, n}) • exponent comparisons: • O(m + n) • creation of new nodes for d • O(m + n) • Time complexity: • O(m + n)

  39. Erasing Polynomials • A hypothetical user who wishes to read in polynomials a(x),b(x) & d(x) and then compute e(x)=a(x)*b(x)+d(x) polyPointer a, b, d, e . a=readPoly(); b=readPoly(); d=readPoly(); temp=pmult(a,b); e=padd(temp,d); printPoly(e); We created temp(x) only to hold a partial result for d(x). By returning the nodes of temp(x). We may use them to hold other polynomials.

  40. Polynomials • Erasing a polynomial void erase(poly_ptr *pptr) { poly_ptr temp; while (*pptr) { temp = *pptr; *pptr = (*pptr)->link; free(temp); } } • useful to reclaim the nodes that are being used to represent partial result such as temp(x)

  41. NULL Polynomials • Allocating/deallocating nodes • how to preserve free node in a storage pool? • initially link together all free nodes into a list in a storage pool • avail: variable of type poly_ptr that points to the first node in list of free nodes storage pool 1 2 n avail ······ initial available space list

  42. Polynomials • Allocating nodes poly_ptr get_node(void) { poly_ptr node; if (avail) { node = avail; avail = avail->link; } else { node = (poly_ptr)malloc(sizeof(poly_node)); if (IS_FULL(node)) { fprintf(stderr,”The memory is full\n”); exit(1); } } return node; }

  43. Polynomials • Deallocating nodes void ret_node(poly_ptr ptr) { ptr->link = avail; avail = ptr; }

  44. Polynomials void erase(poly_ptr *pptr) { poly_ptr temp; while (*pptr) { temp = *pptr; *pptr = (*pptr)->link; ret_node(temp); } } • traverse to the last node in the list: • O(n) where n: number of terms • how to erase polynomial efficiently? • how to return n used nodes to storage pool?

  45. Polynomials • Representing polynomials as circularly linked list • to free all the nodes of a polynomials more efficiently • modify list structure • the link of the last node points to the first node in the list • called circular list (« chain) ptr

  46. Polynomials • Maintain our own list (as a chain) of nodes that has been freed • obtain effective erase algorithm void cerase(poly_ptr *pptr) { if (*pptr) { temp = (*pptr)->link; (*pptr)->link = avail; avail = temp; *pptr = NULL; } } • independent of the number of nodes in a list: O(1)

  47. Polynomials with header nodes • When we implement the other polynomial operations we must handle the zero polynomial as a special case. • To avoid this special case, we introduce a header node into each polynomial, that is each polynomial, zero or non zero, contains one additional node. • The expon & coef fields of this node are irrelevant. • To simplify the addition for polynomials represented as circular lists, we set the expon field of the header to -1.

  48. Polynomials • Circular list with head nodes • handle zero polynomials in the same way as nonzero polynomials (empty list) - - ptr head node - - ptr head node

  49. Operations for Chains • Inverting (or reversing) a chain • “in place” by using three pointers • lead, middle, trail typedef struct list_node *list_ptr; typedef struct list_node { char data; list_ptr link; }; list_ptr invert(list_ptr lead) { list_ptr middle, trail; middle = NULL; while (lead) { trail = middle; middle = lead; lead = lead->link; middle->link = trail; } return middle; } time: O(length of the list)

  50. middle lead NULL NULL trail middle lead NULL NULL trail middle lead Operations for Chains

More Related