Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Objectives of these slides: to describe linked lists in C 6 – Lists.

Similar presentations


Presentation on theme: "1 Objectives of these slides: to describe linked lists in C 6 – Lists."— Presentation transcript:

1 1 Objectives of these slides: to describe linked lists in C 6 – Lists

2 2 Overview 1. List Data Structures and Operations 2. List Implementations 3. Dynamically Created Lists 4. Converting a String to a List 5. List Functions

3 3 1. List Data Structures and Operations Some possible operations: create/destroy a list test to see if a list is empty return the tail of the list insert/delete elements print a list calculate the length of a list

4 4 2. List implementations Version 1: #define N 1000 /* the size of the list */ typedef char LIST[N]; LIST lt; /* same as char lt[N] */

5 5 Version 2 struct listnode { char data; struct listnode *nextptr; }; typedef struct listnode LISTNODE; LISTNODE elem; elem datanextptr

6 6 Use LISTNODE a, b, c; a.data = 'a'; b.data = 'c'; c.data = 'e'; a.nextptr = b.nextptr = c.nextptr = NULL; continued abc

7 7 a.nextptr = &b; b.nextptr = &c; printf("%c", a.nextptr->data); /* 'c' printed */ printf("%c", a.nextptr->nextptr->data); /* 'e' printed */ abc NULL ‘a’‘c’‘e’

8 8 3. Dynamically Created Lists /* list implementation as before */ typedef LISTNODE *LNP; LNP head = NULL; head = malloc(sizeof(LISTNODE)); head->data = 'n'; head->nextptr = NULL; Function prototype in stdlib.h : void *malloc(size_t size); head ‘n’ NULL

9 9 Add a second element head->nextptr = malloc(sizeof(LISTNODE)); head->nextptr->data = 'e'; head->nextptr->nextptr = NULL; head ‘n’‘e’ NULL

10 10 Add a third element head->nextptr->nextptr = malloc(sizeof(LISTNODE)); head->nextptr->nextptr->data = 'w'; head->nextptr->nextptr->nextptr = NULL; head ‘n’‘e’‘w’ NULL

11 11 4. Converting a String to a List #include #include /* list type implementation */ LNP string_to_list(char []); int main() { LNP h = NULL; h = string_to_list("AB"); return 0; } /* implementation of string_to_list() */

12 12 LNP string_to_list(char s[]) { LNP head = NULL, tail; int i; if (s[0] != '\0') { head = malloc(sizeof(LISTNODE)); head->data = s[0]; tail = head; for (i=1; s[i] != '\0'; i++){ tail->nextptr = malloc(sizeof(LISTNODE)); tail = tail->nextptr; tail->data = s[i]; } tail->nextptr = NULL; /* list end */ } return head; }

13 13 string_to_list("AB") head = malloc(sizeof(LISTNODE)); head->data = s[0]; tail = head; head ‘A’ tail ‘?’

14 14 tail->nextptr = malloc(sizeof(LISTNODE)); head ‘A’ tail ‘?’

15 15 tail = tail->nextptr; tail->data = s[i]; /* i = 1 here */ head ‘A’ tail ‘?’‘B’

16 16 s[2] = '\0‘; /* so end of list is assigned NULL */ head ‘A’ tail NULL ‘B’

17 17 5. List Functions 5.1. Empty Lists 5.2. Return the First Element of a List 5.3. Produce the Tail of a List 5.4. Put an Element on the Front of a List 5.5. Insertion continued

18 18 5.6. Deletion 5.7. List Membership 5.8. Print a List 5.9. List Length 5.10. Concatenate Two Lists

19 19 5.1. Empty Lists Make an empty list: LNP h1; h1 = NULL; Test for emptiness: int isempty(LNP sptr) { return (sptr == NULL); }

20 20 5.2. Return the First Element of a List char first(LNP cptr) { if (isempty(cptr)) return '\0‘; else return cptr->data; }

21 21 Use LNP head; char c; head = string_to_list("new"); c = first(head); /* c is 'n'; head is not altered */

22 22 5.3. Produce the tail of a list void tail(LNP *cptr) { LNP temp; if (isempty(*cptr)) printf("The list is empty.\n\n"); else { temp = *cptr; *cptr = (*cptr)->nextptr; free(temp); } } cptr is the address of a pointer, so that the pointer can be modified using "call by reference".

23 23 Use LNP head; head = string_to_list("new"); : tail(&head); /* head is now the list version of “ew” */

24 24 5.4. Put an Element on the List Front LNP cons(char c, LNP cptr) { LNP temp; temp = malloc(sizeof(LISTNODE)); temp->data = c; temp->nextptr = cptr; return temp; }

25 25 Use LNP h1, h2; h1 = string_to_list("ew"); h2 = cons('n', h1); Before the cons() call: h1 ‘e’‘w’ NULL

26 26 Aft er: h2 ‘n’‘e’‘w’ NULL h1

27 27 5.5. Insertion Befor e: head ‘n’‘w’ previousptrcurrentptr NULL newptr ‘o’ NULL

28 28 head ‘n’‘o’‘w’ NULL Aft er:

29 29 Code void insert(LNP *sptr, char value) { LNP newptr, previousptr, currentptr; newptr = malloc(sizeof(LISTNODE)); if (newptr) { newptr->data = value; newptr->nextptr = NULL; previousptr = NULL; currentptr = *sptr; continued

30 30 while ((currentptr != NULL) && (value > currentptr->data)) { previousptr = currentptr; currentptr = currentptr->nextptr; } if (previousptr == NULL) { newptr->nextptr = *sptr; *sptr = newptr; } else { previousptr->nextptr = newptr; newptr->nextptr = currentptr; } } else printf("No memory available.\n"); }

31 31 Note The use of a pointer address (sptr) as an argument to insert() is to allow the head pointer to the list to be altered if the character is inserted as the first node.

32 32 Use LNP h1; h1 = string_to_list("nw"); insert(&hl, 'o'); Dangers: LNP h1, h2; h1 = string_to_list("nw"); h2 = h1; insert(&hl, 'o');

33 33 5.6. Deletion LNP head; head = string_to_list("new"); c = delete(&head, 'e'); head ‘n’ previousptrcurrentptr ‘e’‘w’ NULL

34 34 head ‘n’ previousptrcurrentptr ‘e’‘w’ NULL tempptr

35 35 Code char delete(LNP *sptr, char value) { LNP previousptr, currentptr, tempptr; if (value == (*sptr)->data) { tempptr = *sptr; *sptr = (*sptr)->nextptr; free(tempptr); return value; } else { previousptr = *sptr; currentptr = (*sptr)->nextptr; continued

36 36 while ((currentptr != NULL) && (currentptr->data != value)) { previousptr = currentptr; currentptr = currentptr->nextptr; } if (currentptr) { tempptr = currentptr; previousptr->nextptr = currentptr->nextptr; free(tempptr); return value; } } return '\0'; }

37 37 Some Comments The use of a pointer address (sptr) as an argument to delete() is to allow the head pointer to the list to be altered if the first character in the list is being deleted.

38 38 delete() can stop when: 1. It has found the character. 2. It has reached the end of the list (the character isn't there). 3. It has reached a character lexically bigger than the one being sought. Not used in this code.

39 39 Dangers LNP h1, h2; char c; h1 = string_to_list("all"); h2 = h1; c = delete(&h1, 'l'); h2 would be pointing at nothing if the first node of h1 was deleted h1 ‘a’‘l’ NULL h2

40 40 5.7. List Membership int member(char c, LNP cptr) { if (isempty(cptr)) return 0; else { if (c == first(cptr)) return 1; else return member(c, cptr->nextptr); } }

41 41 5.8. Print a List (iteratively) void printList(LNP cptr) { if (!cptr) printf("List is empty.\n\n"); else { printf("The list is:\n"); while (cptr) { printf("%c --> ", cptr->data); cptr = cptr->nextptr; } printf("NULL\n\n"); } }

42 42 Use LNP head; head = string_to_list("old"); printList(head); The list is: o --> l --> d --> NULL

43 43 Print a List (recursively) void printList(LNP cptr) { if (isempty(cptr)) printf("NULL"); else { printf("%c --> ", first(cptr)); printList(cptr->nextptr); } }

44 44 5.9. List Length int length(LNP cptr) { if (isempty(cptr)) return 0; else return (1 + length(cptr->nextptr)); }

45 45 5.10. Concatenate Two Lists void concat(LNP a, LNP b) { if (a->nextptr == NULL) a->nextptr = b; else concat(a->nextptr, b); }

46 46 Use LNP h1, h2; h1 = string_to_list("new"); h2 = string_to_list("ton"); concat(h1, h2); /* h1 altered */ print_list(h1); The list is: n --> e --> w --> t --> o --> n --> NULL

47 47 Dangers LNP h1, h2; h1 = string_to_list("ab"); h2 = string_to_list("cd"); concat(h1, h2); /* h1 is list "abcd" */ h2->data = 'o'; h1 ‘a’‘o’‘d’ NULL ‘b’ h2

48 48 5.11 Doubly Linked Lists A node in a doubly-linked list contain two references that point to the next node and the previous node. ex.struct listnode { char data; struct listnode *next; struct listnode *prev; }; front points to the first node in the list back points at the last node in the list

49 49 A doubly-linked list can be scanned in both directions: a forward scan starts at ' front ' and ends when the link is to the same object as ' back ' a backward scan starts at ' back ' and ends when the link is to the same object as ' front '

50 50 Like a singly-linked list, a doubly linked list is a sequential structure. To move forward or backward, use the node links 'next' and 'prev'. Unlike a singly linked list, the insert and delete operations only need a single reference to the node.

51 51 Insert a list into double linked list Insertion into a doubly linked list requires four reference assignments. prevNode = curr.prev; newNode.prev = prevNode;// 1 prevNode.next = newNode;// 2 curr.prev = newNode;// 3 newNode.next = curr;// 4

52 52 Delete a list from double linked list To delete a node curr, link the predecessor ( curr.prev ) of ' curr ' to the successor of ' curr ' ( curr.next ). prevNode = curr.prev; succNode = curr.next; succNode.prev = prevNode;// 1 prevNode.next = succNode;// 2 curr.prev = null; curr.next = null;


Download ppt "1 Objectives of these slides: to describe linked lists in C 6 – Lists."

Similar presentations


Ads by Google