Sorting LinkedLists
QuickSort Review What is needed to do quick sort efficiently?
QuickSort Review What is needed to do quick sort efficiently? partitionFunction must be O(n)
Bad Partition Partition list from indexes low to high: pivotValue = value at low i = low+1 //current index in left half j = high //current index in right half while i <= j while list[i] <= pivotValue and i <= j increase i while list[j] >= pivotValue and i <= j decrease j if i < j swap list[i] and list[j] swap values at list[low] and list[j] return new location of pivot
Bad Partition list.at(index) and list.set(index, value) are O(n) Partition list from indexes low to high: pivotValue = value at low i = low+1 //current index in left half j = high //current index in right half while i <= j while list[i] <= pivotValue and i <= j increase i while list[j] >= pivotValue and i <= j decrease j if i < j swap list[i] and list[j] swap values at list[low] and list[j] return new location of pivot
Better Partition Need to work in terms of pointers Partition list between pointers low and high: pivotValue = value pointed to by low i = low->next //current pointer in left half j = high //current pointer in right half while i != j while value j points to >= pivotValue and i != j j = j->prev while value i points to <= pivotValue and i != j i = i->next if i != j swap value i points to and value j points to swap values pointed to by low and j return new j
QuickSort Review What is needed to partition in O(n)? Partition list between pointers low and high: pivotValue = value pointed to by low i = low->next //current pointer in left half j = high //current pointer in right half while i != j while value j points to >= pivotValue and i != j j = j->prev while value i points to <= pivotValue and i != j i = i->next if i != j swap value i points to and value j points to swap values pointed to by low and j return new j
Partition list between pointers low and high: pivotValue = value pointed to by low i = low->next //current pointer in left half j = high //current pointer in right half while i != j while value j points to >= pivotValue and i != j j = j->prev while value i points to <= pivotValue and i != j i = i->next if i != j swap value i points to and value j points to swap values pointed to by low and j return new j QuickSort Review What is needed to partition in O(n)? O(n) : – set i, j pointers – swap two elements given pointers
Partition list between pointers low and high: pivotValue = value pointed to by low i = low->next //current pointer in left half j = high //current pointer in right half while i != j while value j points to >= pivotValue and i != j j = j->prev while value i points to <= pivotValue and i != j i = i->next if i != j swap value i points to and value j points to swap values pointed to by low and j return new j QuickSort Review What is needed to partition in O(n)? O(n) : – set i, j pointers – swap two elements given pointers O(1) : – move left or right one element – compare elements – swap elements
QuickSort DLL could use existing quicksort in nlogn SLL can not Singly LinkedDoubly Linked Move LeftO(n)O(1) Move RightO(1) Compare Elements O(1) Swap ElementsO(n) If just have pointers to two elements O(1)
QuickSort Could get smarter and adapt for LinkedList: Remove first item from list, point to with pivot
QuickSort Could get smarter and adapt for LinkedList:
QuickSort Could get smarter and adapt for LinkedList: Remove first item from list, point to with pivot
QuickSort Could get smarter and adapt for LinkedList: Remove each element, add to small or large lists
QuickSort Could get smarter and adapt for LinkedList: Remove each element, add to small or large lists
QuickSort Could get smarter and adapt for LinkedList: Remove each element, add to small or large lists
QuickSort Could get smarter and adapt for LinkedList: Make new list from small + pivot + large
QuickSort Could get smarter and adapt for LinkedList: Make new list from small + pivot + large
QuickSort Could get smarter and adapt for LinkedList: Make new list from small + pivot + large
QuickSort Could get smarter and adapt for LinkedList: Return pivot from partition function
MergeSort MergeSort with array – Disadvantages?
MergeSort MergeSort with array – Need O(n) extra storage – Lots of copy overhead In place trades LOTS of copying for less storage
MergeSort What is needed to do efficently?
MergeSort What is needed to do efficiently? Slice in half in O(n) Merge in O(n)
Slice Slice list in half: – Produce second linked list with second half
Slice Slice list in half: – Walk to last node before halfway point
Slice Slice list in half: – Break off second part, update lengths
MergeIn MergeList : Combine elements from two sorted lists – MainList ends with all sorted, SecondList ends empty
MergeList : Combine elements from two sorted lists – Use pointer with dummy to build new list MergeIn
MergeList : Combine elements from two sorted lists – Use endMerged pointer to track end of new list MergeIn
MergeList : Combine elements from two sorted lists – Pick smallest head of original two lists, attach to new list MergeIn
MergeList : Combine elements from two sorted lists – Detach from its home list, make it end of new list MergeIn
MergeList : Combine elements from two sorted lists – Now pick next smallest head, attach end to it MergeIn
MergeList : Combine elements from two sorted lists – Detach that from its home, update end MergeIn
MergeList : Combine elements from two sorted lists – Continue… MergeIn
MergeList : Combine elements from two sorted lists – Continue… until both original lists are empty MergeIn
MergeList : Combine elements from two sorted lists – Hook first list to the start of the new sequence MergeIn
MergeList : Combine elements from two sorted lists – Update length of combined list MergeIn
Final Sort With split/merge, sort part is easy