Linked Lists
Linked List Group of nodes connected by pointers A node consists of Data Pointer to next node 6 5 3 8 Head Null
Insertion into a Linked List Insert 9 after 5 6 5 3 8 Head Null 9
Deletion from a Linked List Delete 3 from the list Free this space 6 5 3 8 Head Null 9
Declaration of a node struct node { int info; struct node *next; }; typedef struct node node; 6 5 3 8 Head Null
Linked List Structure 6 5 3 8 Head Null Some address In memory 6 5 3 8 Points back to Internal node
Dynamic allocation of a node node *ptr; ptr = (node *)malloc(sizeof(node)); ptr ? free(ptr)
Dynamic allocation of a node node *ptr; ptr = (node *)malloc(sizeof(node)); free(ptr); ? Memory Problems ? ? ptr
Dynamic allocation of a node Fox01>valgrind ./memoryleakexample ==19325== HEAP SUMMARY: ==19325== in use at exit: 32 bytes in 2 blocks ==19325== total heap usage: 3 allocs, 1 frees, 48 bytes allocated ==19325== ==19325== LEAK SUMMARY: ==19325== definitely lost: 32 bytes in 2 blocks ==19325== indirectly lost: 0 bytes in 0 blocks ==19325== possibly lost: 0 bytes in 0 blocks ==19325== still reachable: 0 bytes in 0 blocks ==19325== suppressed: 0 bytes in 0 blocks ==19325== Rerun with --leak-check=full to see details of leaked memory ==19325== For counts of detected and suppressed errors, rerun with: -v ==19325== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Dynamic allocation of a node node *ptr, *ptr2, *ptr3; ptr = (node *)malloc(sizeof(node)); ptr2 = (node *)malloc(sizeof(node)); ptr3 = (node *)malloc(sizeof(node)); ? ptr ? ptr2 ? ptr3
Dynamic allocation of a node ptr -> info = 3; ptr2 -> info = 5; ptr3 -> info = 7; 3 ptr 5 ptr2 7 ptr3
Dynamic allocation of a node ptr -> next = ptr2; ptr2 -> next = ptr3; ptr3 -> next = NULL; ptr 3 5 ptr2 7 ptr3 NULL
Dynamic allocation of a node node *ptr; ptr = (node *)malloc(sizeof(node)); ptr-> next = (node *)malloc(sizeof(node)); ptr-> next ->next = (node *)malloc(sizeof(node)); ptr -> next -> next ->next = NULL; ptr ? ? ? NULL
Inserting at the Head Allocate a new node Insert new element Make new node point to old head Update head to point to new node 6 5 3 8 Head Null 2 6 5 3 8 Head Null
Inserting at the Head Memory Problems void inserthead(node *head, int a) { node *ptr; ptr->info = a; ptr->next = head; head = ptr; } inserthead(head,2); Memory Problems 6 5 3 8 Null Head Head 2 6 5 3 8 Null
Inserting at the Head Can not modify head void inserthead(node *head, int a) { node *ptr; ptr = (node*)malloc(sizeof(node)); ptr->info = a; ptr->next = head; head = ptr; } inserthead(head,2); Can not modify head 6 5 3 8 Null Head Head 2 6 5 3 8 Null
Inserting at the Head node *inserthead(node *head, int a) { node *ptr; ptr = (node*)malloc(sizeof(node)); ptr->info = a; ptr->next = head; return(ptr); } head = inserthead(head,2); 6 5 3 8 Null Head 2 6 5 3 8 Head Null
Removing at the Head Update head to point to next node in the list Allow garbage collector to reclaim the former first node 6 5 3 8 Head Null 5 3 8 Head Null
Removing at the Head void deletehead(node *head) { head = head->next; return; } deletehead(head); Memory Leak 6 5 3 8 Head Null 5 3 8 Head Null
Removing at the Head void deletehead(node *head) { node * ptr; ptr = head; head = head->next; free(ptr); return; } deletehead(head); Can not modify head 6 5 3 8 Head Null 5 3 8 Head Null
Removing at the Head node* deletehead(node *head) { node * ptr; ptr = head; head = head->next; free(ptr); return(head); } head = deletehead(head); 6 5 3 8 Head Null 5 3 8 Head Null
Inserting at the Tail Allocate a new node Insert new element Have new node point to null Have old last node point to new node 6 5 3 8 Head Null 6 5 3 8 1 Null Head
Inserting at the Tail node *inserttail(node *head, int a) { node *ptr; node *ptr2 = head; ptr = (node*)malloc(sizeof(node)); ptr->info = a; ptr->next = NULL; if (head == NULL) return (ptr); else if (head->next == NULL) { head->next = ptr; return (head); } while (head->next != NULL) head = head->next; return(ptr2); 6 5 3 8 Head Null
Print a linked list printlist(head); void printlist (node *head) { while (head !=NULL) printf("%d ",head->info); head = head->next; } printf("\n"); printlist(head); 6 5 3 8 Head Null
Find length of a linked list int length(node *head) { int len = 0; while (head != NULL) { head = head->next; len = len + 1; } return(len); x=length(head); 6 5 3 8 Head Null
Free a linked list void freelist(node *head) { node *ptr=head; while(head != NULL) { head = head->next; free(ptr); ptr = head; } freelist(head); 6 5 3 8 Head Null
Find the sum of elements in a linked list int sum(node *head) { int total = 0; while (head !=NULL) total = total + head-> info; head = head->next; } return (total); 6 5 3 8 Head Null
Find the last element in a linked list int last(node *head) { if (head == NULL) return (-1); else if (head->next == NULL) return(head-> info); while (head->next != NULL) head = head -> next; return (head->info); } 6 5 3 8 Head Null
Find if an element appears in a linked list int exists(node *head, int x) { if (head == NULL) return (0); while (head != NULL) if (head->info == x) return (1); head = head -> next; } 6 5 3 8 Head Null
Find if a linked list is sorted in increasing order int sorted(node *head) { if (head == NULL) return (1); else if (head->next == NULL) while (head->next != NULL) if (head->info > head->next->info) return (0); head = head -> next; } 6 5 3 8 Head Null
Review of Recursion
Recursive Functions A function that invokes itself is a recursive function. long fact(int k) { if (k == 0) return 1; else return k*fact(k-1) } k!=k*(k-1)! Available on class webpage as lecture3e6.c
Recursive Factorial Function 24 4*fact(3) 6 3*fact(2) 2 2*fact(1) 1 1*fact(0)
Fibonacci Numbers Sequence {f0,f1,f2,…}. First two values (f0,f1) are 1, each succeeding number is the sum of previous two numbers. 1 1 2 3 5 8 13 21 34 F(0)=1, F(1) = 1 F(i) = F(i-1)+F(i-2)
Fibonacci Numbers int fibonacci(int k) { int term; term = 1; if (k>1) term = fibonacci(k-1)+fibonacci(k-2); return term; } Available on class webpage as lecture3e7.c Iterative version available on class webpage as lecture3e8.c
Recursive Fibonacci Function 2 1 Fibonacci(2) Fibonacci(1) 1 1 Fibonacci(1) Fibonacci(0)
Exercise Write a function to compute the following Recursion Step
Solution long add(int a, int b) { if (b == a) return a; else return b+add(a,b-1); }
Linked Lists and Recursion
Find the length of a linked list int length(node *head) { int count=0; while (head != NULL) head = head->next; count++; } return (count); x=length(head); 6 5 3 8 Head Null
Recursive: Find the length of a linked list int length(node *head) { if (head == NULL) return 0; else return 1 + length(head->next); } x=length(head); 6 5 3 8 Head Null
Find the sum of elements in a linked list int sum(node *head) { int total = 0; while (head !=NULL) total = total + head-> info; head = head->next; } return (total); 6 5 3 8 Head Null
Recursive: Find the sum of elements in a linked list int sum2(node *head) { if (head == NULL) return (0); else return (head->info + sum2(head->next)); } 6 5 3 8 Head Null
Find the last element in a linked list int last(node *head) { if (head == NULL) return (-1); else if (head->next == NULL) return(head-> info); while (head->next != NULL) head = head -> next; return (head->info); } 6 5 3 8 Head Null
Recursive: Find the last element in a linked list int last2(node *head) { if (head == NULL) return (-1); else if (head->next == NULL) return(head->info); return(last2(head->next)); } 6 5 3 8 Head Null
Find if an element appears in a linked list int exists(node *head, int x) { if (head == NULL) return (0); while (head != NULL) if (head->info == x) return (1); head = head -> next; } 6 5 3 8 Head Null
Recursive: Find if an element appears in a linked list int exists2(node *head, int x) { if (head == NULL) return (0); if (head->info == x) return 1; else return(exists2(head->next, x)); } 6 5 3 8 Head Null
Find if a linked list is sorted in increasing order int sorted(node *head) { if (head == NULL) return (1); else if (head->next == NULL) while (head->next != NULL) if (head->info > head->next->info) return (0); head = head -> next; } 6 5 3 8 Head Null
Recursive: Find if a linked list is sorted in increasing order int sorted2(node *head) { if (head == NULL) return(1); else if (head->next == NULL) return (1); else if (head->info > head->next->info) return (0); return(sorted2(head->next)); } 6 5 3 8 Head Null
Find maximum in a linked list int max(node *head) { int maximum; if (head == NULL) return(-1); maximum = head->info; while (head != NULL) { if (head->info > maximum) head = head->next; } return(maximum); 6 5 3 8 Head Null
Recursive: Find maximum in a linked list int recursivemax(node *head) { int temp; if (head == NULL) return (-1); temp = recursivemax(head->next); if (head->info > temp) return (head->info); else return (temp); } 6 5 3 8 Head Null
Find second largest element in a linked list int secondlargest(node *head) { int large,large2; if (head == NULL) return(-1); if (head->next == NULL) return(-1); if (head->info > head->next->info) { large = head->info; large2 = head->next->info; } else { large2 = head->info; large = head->next->info; head = head->next->next; while (head != NULL) { if (head->info > large) { large2 = large; large = head->info; } else if (head->info > large2) large2 = head->info; head = head->next; return(large2); 6 5 3 8 Head Null
Recursive: Find second largest element in a linked list int recursivesecondlargest(node *head, int *largest) { int large, large2; if (head == NULL) return(-1); if (head->next == NULL) *largest = head->info; } large2 = recursivesecondlargest(head->next, &large); if (head->info > large) { large2 = large; *largest = head->info; } else if (head->info > large2){ *largest = large; large2 = head->info; return large2; 6 5 3 8 Head Null
Exercise1 Given a linked list and two integers m and n, traverse the linked list such that you retain m nodes and delete the next n nodes, continue doing this until the end of the linked list 1 2 3 4 5 6 7 8 Head1 Null m n m n m=2, n=2 After the operation we have the following lists 1 2 5 6 Head1 Null
Exercise1 1 2 3 4 5 6 7 8 Head1 Null m n m n node *skipandremove(node *head, int m, int n) { node *ptr = head, *t, *temp; int count; while (ptr != NULL) { for (count=1; count<m && ptr != NULL; count++) ptr = ptr -> next; if (ptr == NULL) return (head); t = ptr->next; for (count=1; count<=n && t != NULL; count++) { temp = t; t = t->next; free(temp); } ptr->next = t; ptr = t; return(head);
Exercise2 Given a linked list, move the last element to the front of the linked list 1 2 3 4 5 6 7 8 Head1 Null After the operation we have the following list 8 1 2 3 4 5 6 7 Head1 Null
Exercise2 1 2 3 4 5 6 7 8 Head1 Null prev last node *movelasttofront(node *head) { node *prev; node *last=head; while (last->next != NULL) prev = last; last = last -> next; } prev->next = NULL; last->next = head; head = last; return (head);
Exercise3 Given a linked list, return the nth node from the end of a linked list 1 2 3 4 5 6 7 8 Head1 Null n=3 After the operation we have the following list 6
Exercise3 1 2 3 4 5 6 7 8 Head1 Null ptr2 ptr node* nthfromlast(node *head, int n) { node *ptr=head, *ptr2=NULL; int count=0; for (count=0; count<n && ptr!=NULL; count++) ptr=ptr->next; if (ptr==NULL && count == n) return head; else if (ptr==NULL) return NULL; ptr2 = head; while (ptr != NULL) { ptr = ptr->next; ptr2 = ptr2 ->next; } return(ptr2);
Exercise4 Given a linked list, reverse the linked list and return the new list 1 2 3 4 5 6 7 8 Head1 Null After the operation we have the following list 8 7 6 5 4 3 2 1 Head1 Null
Exercise4 node *reverse(node *head) { 5 6 7 8 Null Exercise4 current next 4 3 2 1 Prev Null node *reverse(node *head) { node* prev= NULL,*current = head, *next; while (current != NULL) next = current->next; current->next = prev; prev = current; current = next; } return (prev);
Exercise5 Given a linked list, return 1 if there is a loop in the linked list and return 0 otherwise. 1 2 3 4 5 6 7 8 Head1 Return 1 for above list 1 2 3 4 5 6 7 8 Head1 Null Return 0 for above list
Exercise5 1 2 3 4 5 6 7 8 Head1 int detectloop(node *head) { node *ptr = head, *ptr2 = head; while (ptr!=NULL && ptr2!=NULL && ptr2->next!=NULL) ptr = ptr->next; ptr2 = ptr2->next->next; if (ptr == ptr2) return 1; } return 0;
Return kth node in a list Given a linked list, return the kth node from the front of the linked list node *returnkthnode(node *head, int k) 1 2 3 4 5 6 7 8 Head1 Null singlenode = returnkthnode(head1,3); 3 singlenode Null
Recursive: Return kth node in a list Given a linked list, return the kth node from the front of the linked list node *returnkthnode2(node *head, int k) 1 2 3 4 5 6 7 8 Head1 Null singlenode = returnkthnode2(head1,3); 3 singlenode Null
Check if all the infos in a linked list are distinct Given a linked list, return 1 if all infos are distinct and 0 otherwise int alldistinct(node *head) 1 2 3 4 5 6 7 8 Head1 Null x = alldistinct(head1); 1 x
Recursive: Check if all the infos in a linked list are distinct Given a linked list, return 1 if all infos are distinct and 0 otherwise int alldistinct2(node *head) 1 2 3 4 5 6 7 8 Head1 Null x = alldistinct2(head1); 1 x
Concatenate two lists Given two linked lists, concatenate the second list to the end of first list node *concatenate(node *list1, node *list2) 1 2 3 4 list1 Null 5 6 7 8 list2 Null list3 = concatenate(list1,list2); list1 list2 1 2 3 4 5 6 7 8 list3 Null
Recursive: Concatenate two lists Given two linked lists, concatenate the second list to the end of first list node *concatenate2(node *list1, node *list2) 1 2 3 4 list1 Null 5 6 7 8 list2 Null list3 = concatenate2(list1,list2); list1 list2 1 2 3 4 5 6 7 8 list3 Null