180 likes | 199 Views
Linked Lists. Merge Sorted Lists. Write an algorithm that merges two sorted linked lists The function should return a pointer to a single combined list The two input lists can be destroyed The output list should not contain any duplicate values Unnecessary nodes should be freed.
E N D
Merge Sorted Lists • Write an algorithm that merges two sorted linked lists • The function should return a pointer to a single combined list • The two input lists can be destroyed • The output list should not contain any duplicate values • Unnecessary nodes should be freed
Merge Sorted Lists –Iterative Solution Concept • Traverse lists L1 and L2 using two pointers, and compare elements • If the element from L1 is smaller – move to the next one • If the element from L2 is smaller – insert it into L1 (before the compared L1 element)
Merge Sorted Lists –Iterative Solution MERGE-LISTS (L1, L2) // Simple case – point head to first node of L1. if (L1.val <= L2.val) headL1 else // Special case - first node in L2 is smaller. headL2 // Smallest value is first. temp L2.next // Save pointer to next. L2.nextL1 // The rest of L1 follows. L2temp // Point to next node in L2. prevhead // Save for future insertions.
Merge Sorted Lists –Iterative Solution (continued) // Traverse both lists, insert L2 nodes into L1. while (L1 != null && L2 != null) if (L1.val < L2.val) if (L1.next = null) L1.next L2 // Append remainder of L2. L1null // Exit loop. else prevL1 // Save pointer to previous. L1L1.next // Move to next node.
Merge Sorted Lists –Iterative Solution (continued) else if (L1.val > L2.val) temp L2.next // Save pointer to next. L2.nextL1 // Insert L2 node before L1. prev.nextL2 L2temp // Point to next node in L2. else // (L1.val = L2.val) tempL2 // Save pointer for freeing. L2L2.next // Duplicate – skip it. free (temp) returnhead
Merge Sorted Lists –Recursive Solution MERGE-LISTS (L1, L2) switch caseL1 = null: headL2 caseL2 = null:headL1 caseL1.val < L2.val: headL1 head.next MERGE-LISTS (L1.next, L2) caseL1.val > L2.val: headL2 head.next MERGE-LISTS (L1, L2.next) caseL1.val = L2.val: head L1 head.next MERGE-LISTS (L1.next, L2.next) free (L2) returnhead
Merge Unsorted Lists • What if the lists are not sorted? • If we also want to remove duplicates, must compare each element in one list, with all elements in the other • Complexity: O(n2) • If we give up on this requirement,can we do better?
Merge Unsorted Lists • Yes: simply append the lists APPEND-LIST (L1, L2) if (L1 = null) L1 L2 else curL1 while (cur.next != null) curcur.next cur.next L2
Reverse Linked List • Write a function that accepts a linked list as input, and reverses it in place • No nodes should be freed or created –only the pointers should be changed • We will start by writing an iterative solution, and then give a recursive one
Iterative Reverse ITERATIVE_REVERSE (list) resultnull curlist while (cur != null) nextcur.next cur.next result resultcur curnext listresult
Iterative Reverse –Java Implementation publicvoid iterativeReverse() { ListNode result = null, cur = head, next; while (cur != null) { next = cur.getNext(); cur.setNext (result); result = cur; cur = next; } head = result; }
Recursive Reverse • The straightforward solution: • Save the first element • Reverse the rest of the list • Append the first element and make it last • This will work, but instead of O(n) for the iterative solution, will take O(n2) • Is there an O(n) recursive solution?
Recursive Reverse – O(n2) RECURSIVE_REVERSE (list) if (list = null) return null firstlist restlist.next if (rest = null) returnlist rest RECURSIVE_REVERSE (rest) cur rest while (cur.next != null) curcur.next cur.next first first.next null returnrest
Recursive Reverse – O(n) RECURSIVE_REVERSE (list) if (list = null) return null firstlist restlist.next if (rest = null) returnlist rest RECURSIVE_REVERSE (rest) first.next.next first first.next null returnrest
Recursive Reverse –Java Implementation • When writing pseudocode, a list is simply a pointer to the first element • The type of the list is "pointer to list node" • In Java, the list is wrapped by a class, which contains a head pointer as a field • The list has a type of its own • Only the head field itself is of type "pointer to list node"
Recursive Reverse –Java Implementation • The recursive call needs to get a pointer to the list head as a parameter, but this pointer is a private field • Therefore, a wrapper method should be provided to expose the functionality: public void reverse() { head = reverseRec (head); }
Recursive Reverse –Java Implementation private static ListNode reverseRec (ListNode list) { ListNode first, rest; if (list == null) return null; first = list; rest = list.getNext(); if (rest == null) return list; rest = reverseRec (rest); first.getNext().setNext (first); first.setNext (null); return rest; }