Sorting Decending Order Lecturers : Boontee Kruatrachue Room no. 913 Kritawan Siriboon Room no. 913 Text : Data Structures & Algorithm Analysis in C, C++,… Mark Allen Weiss, Addison Wesley
Sorts List & Tree Sorts Sorting Bubble Sort Selection Sort Insertion Sort Shell Sort Merge Sort Quick Sort List & Tree Sorts Sequential Search (Linear Search) Binary Search Tree AVL (Hight Balanced) Tree B-Tree Heap
เรียง จากน้อย --> มาก Sorting การจัดลำดับ Comparison-based sorting ใช้การเปรียบเทียบในการจัดลำดับ Best case O(n log n) Ascending Order เรียง จากน้อย --> มาก Decending Order เรียงจากมาก --> น้อย
Bubble Sort Ascending Order จากน้อย --> มาก 8 3 9 4 5 Original File After 1st pass: the biggest,9,floats up Key idea : Bubble the largest, Scan from the left, swap unorder successive elements. Each scan (pass) : Floats the largest (or smallest) up in the right place. Remains 1-element-shorter file to process. Repeat bubbling. Then the next largest, etc. 3 8 4 5 9 From 1st pass After 2nd pass: 2nd biggest,8, floats up 3 4 5 8 9 From 2nd pass After 3rd pass: 3rd biggest 5 floats up home
Questions: 8 3 9 4 5 3 8 4 5 9 3 4 5 8 9 Bubble Sort Ascending Order จากน้อย --> มาก Questions: Generally, how many passes needed? _____ How many comparisions performed : pass #1 ______ pass #2 ______ ... Pass # n-1 _____ In the ithscan we perform (___) comparisons. Hence: _____________________ This gives: O(______). Fill in pass #3. Do we need pass #3 ? Why? How do we know ? 8 3 9 4 5 Original File After 1st pass: the biggest,9,floats up n-1 n-1 n-2 1 3 8 4 5 9 From 1st pass After 2nd pass: 2nd biggest,8, floats up n-i (n-1) + (n-2) + ... + 1 n2 No. 3 4 5 8 9 From 2nd pass After 3rd pass: 3rd biggest 5 floats up The file is already order. After pass#3 done : no swapping.
Bubble Sort Pseudocode last_i = n-1 //array size = n swaped = true loop(last_i>=1 && swaped) swaped = false i = 0 loop(i < last_i) if (a[i],a[i+1])unordered swap them i++ last_i -- Inner loop Outer loop 8 3 9 4 5 p0 P1 P2 P3 P4 8 3 9 4 5 +(n-1) 1 2 3 4 1 2 3 4 array size = n Outer loop ทำตั้งแต่ last [n-1,1] inner loop : i [0 , last-1] = last ครั้ง = 1+2+3+...+(n-1) = n * (n-1)/2 = O(n2) 1+2+3+... +(n-3) +(n-2)+(n-1) n * (n-1)/2
Bubble Sort Code 8 3 9 4 5 8 3 9 4 5 typedef int T; //c template <class T> //C++ void bubbleSort(T* a,int n){ int swaped = true; for (int last = n-1; last>0 && swaped; last--){ swaped = false; for(int i=0;i<last;i++) if(a[i]>a[i+1]){ //swap successive elements T t = a[i]; a[i] = a[i+1]; a[i+1] = t; swaped = true; } Outer loop p0 P1 P2 P3 P4 8 3 9 4 5 Inner loop 8 3 9 4 5 1 2 3 4 array size = n Outer loop ทำตั้งแต่ last [n-1,1] inner loop : i [0 , last-1] = last ครั้ง = 1+2+3+...+(n-1) = n * (n-1)/2 = O(n2) 1 2 3 4
Straight Selection Sort (Pushed Down Sort) 6 9 8 5 4 Original File : size n After pass 1 After pass 2 . . . Sorted File: After Pass _____ Ascending Order เรียงจากน้อย --> มาก I’ll choose the biggests first. Key idea : Scan to select the biggest /smallest, swap with the 1st /last element. Each scan (pass) : Floats the largest (or smallest) up in the right place. Remains 1-element-shorter file to process. Repeat selection. home
Straight Selection Sort Analysis 6 9 8 5 4 Original File : size n After pass 1 After pass 2 . . . Sorted File: After Pass _____ Ascending Order เรียงจากน้อย --> มาก Data size = n. How many passes would make the ordered list? _______ passes. Pass #1, # comparisions = __________ Pass #2, # comparisions = __________ Pass #3, # comparisions = __________ ...... ... ... Last Pass #________ # comparisions = __________ Total #comparisions = ______________= __________ = O(___) n-1 n-1 n-2 n-3 n-1 1 1+2+3+...+(n-1) n*(n-1)/2 n2
Straight Selection Sort Pseudocode 6 9 8 5 4 Original File : size n After pass 1 After pass 2 . . . Sorted File: After Pass _____ last = n-1 //array size = n loop(last >= 1) //last > 0 biggest = a[0] big_i = 0 i = 1 loop (i <= last) if (a[i] > biggest) biggest = a[i] big_i = i i++ swap(a[big_i], a[last]) last-- Ascending Order เรียงจากน้อย --> มาก array size = n Outer loop ทำตั้งแต่ last [n-1,1] inner loop : i [1 , last] = last ครั้ง = 1+2+3+...+(n-1) = n * (n-1)/2 = O(n2)
Straight Selection Sort Code typedef int T; //c void selection(T* a, int n){//array size = n //ascending order for(int last = n-1; last > 0; last--){ int ind = 0; for(int biggest = a[0], i = 1; i<=last; i++) if (a[i] > biggest){ biggest = a[i]; big_i = i; } //swaping (last ele.,largest ele.) T t = a[big_i]; a[big_i] = a[last]; a[last] = t; 6 9 8 5 4 Ascending Order เรียงจากน้อย --> มาก array size = n Outer loop ทำตั้งแต่ last [n-1,1] inner loop : i [1 , last] = last ครั้ง = 1+2+3+...+(n-1) = n * (n-1)/2 = O(n2)
8 6 7 5 9 Key idea : Scan to insert the card in sorted file in hand. Insertion Sort 8 6 7 5 9 Key idea : Scan to insert the card in sorted file in hand. Each scan (pass) : Compare to insert the the right place to insert. If that is not the place, move that data next to its old place to give the room for the inserted card. Remains 1-element-shorter file to process. Repeat insertion. Ascending Order จากน้อย --> มาก home
8 6 7 5 9 array size = n Outer loop ทำตั้งแต่ i [1,n-1] Insertion Sort //ascending order, array size = n // loop inserting i-th element i = 1 // start form 2nd element loop (i < n) insertEle = a[i]; // find insert position ip ip = i ; loop (ip > 0 && insertEle <= a[ip-1]) a[ip] = a[ip-1]; //shift out other data ip-- // to make place for a[ip] = insertEle; // insertElement i++; // for next insertElement 8 6 7 5 9 Ascending Order จากน้อย --> มาก array size = n Outer loop ทำตั้งแต่ i [1,n-1] inner loop : ip[1 , i] = i ครั้ง = 1+2+3+...+(n-1) = n * (n-1)/2 = O(n2) home
8 6 7 5 9 Insertion Sort Insertion Sort Original File : size = n After pass 1 After pass 2 Sorted file : after pass __ Data size = n, how many passes? ____ Pass #1, # comparisions: minimum = ____ maximum =____ Pass #2, # comparisions: minimum = ____ maximum =____ Last Pass #_____ # comparisions: minimum = ____ maximum =____ Total #comparisions Worst case = ____________ = _________= O(__) When?____________ Best case = ____________ = _________= O(__) When?____________ n-1 1 1 1 2 n-1 1 n-1 1+2+3+...+(n-1) n*(n-1)/2 n2 Reverse Ordered List 1+1+...+1 (n-1) n Ordered List
8 6 7 5 9 Insertion Sort Code array size = n //ascending order, typedef int T; //c void insertion ( T* a, int n) {//array size = n int ip; //inserting position //loop inserting i-th element for ( int i = 1 ; i < n; i++ ) { //find insert position ip insertEle = a[i]; // find insert position ip for(ip = i; ip > 0 && insertEle <= a[ip-1]; ip--) a[ip] = a[ip-1]; // shift out other data to make place for insertElement a[ip] = a[i]; // a[i] is an inserting element } Ascending Order จากน้อย --> มาก array size = n Outer loop ทำตั้งแต่ i [1,n-1] inner loop : ip[i , 1] = i ครั้ง = 1+2+3+...+(n-1) = n * (n-1)/2 = O(n2)
Insertion Sort 4 1 6 5 3 2 p=4 1 4 5 6 3 2 j p1 p2 p3 p4 p5 p6 tmp=3 typedef int T; //c void insertionSort(T a[], int n){ //size = n int j; for( int p = 1; p < n; p++ ){ T tmp = a[ p ]; for(j = p; j > 0 && tmp < a[j-1];j--) //line* a[ j ] = a[ j - 1 ]; a[ j ] = tmp; } p1 p2 p3 p4 p5 p6 4 1 6 5 3 2 tmp=3 p=4 1 4 5 6 3 2 1 2 3 4 5 # times of comparisions = # times of line* j = 1+2+3+...+(n-1) = n*(n-1) /2 = O(n2) Outer loop : p = 1 to n-1 Inner loop : j = p to 1, p times
Shell Sort (Diminishing Increment Sort) กำหนด incremental Sequence ของ interger กี่ตัวก็ได้ ตัวแรกเป็น 1 ไล่เพิ่มน้อยไปมาก i1, i2, ..., imax เช่น 1 3 5 แบ่ง file ใหญ่ เป็น file ย่อย n files ตามค่า i ใน incremental Sequence ครั้งแรกใช้ imax ตัวที่มากที่สุดแบ่ง ดังนั้นถ้าใช้ 1 3 5 ต้องใช้ 5 มาทำการแบ่งก่อน วิธีแบ่ง file ใหญ่ เป็น n file ย่อย นับข้อมูลทีละตัวไล่ไปตามลำดับตั้งแต่ 1 ถึง n เมื่อครบ n ให้เริ่มนับ 1 ถึง n ใหม่ ทำเช่นนี้ไปเรี่อยๆ จะได้ข้อมูล n กลุ่ม ตามหมายเลขที่นับ ใช้ 5 แบ่งได้ 5 files ย่อย ตามสี ดังแสดงข้างล่าง Insertion sort แต่ละ file ย่อยทุก file ได้ผลลัพธ์อยู่ในตำแหน่งของแต่ละ file ย่อย จะเห็นว่าในครั้งแรก data วิ่งไกล ทำขั้นตอน 2-4 ใหม่โดยใช้ค่า i ตัวที่มากรองลงมา เมื่อทำการแบ่ง file โดยใช้ i = 1 ในที่สุด ก็จะทำ insertion sort กับข้อมูลทุกตัวพร้อมกัน จึงเรียก Diminishing Increment Sort เพราะ ใช้ incremental sequence ตัวที่ลดลงเรี่อยๆ Donald Shell 1 2 3 4 5 10 11 13 6 12 8 7 9 Insertion sort (Ascending) 6 4 1 5 2 7 9 3 13 8 10 11 12 home
Shell Sort (Diminishing Increment Sort) กำหนด incremental Sequence i1, i2, ..., imax เช่น 1 3 5 for (int n = max; n >=1; n--) แบ่ง file ใหญ่ เป็น n file ย่อย insertion sort แต่ละ file ย่อย start Diminishing ลดลง 1 2 3 4 5 10 11 13 6 12 8 7 9 Insertion n มาก →file เล็ก insertion sort O(n2) ok n น้อย → ค่อนค่าง sorted insertion sort ดี O(n) 6 4 1 5 2 7 9 3 13 8 10 11 12 1 2 3 6 4 5 7 9 13 8 10 11 12 8 6 7 5 9 Insertion 5 2 1 6 3 7 8 4 11 9 10 13 12 1 5 2 6 3 7 8 4 11 9 10 13 12 Insertion Insertion Sort Best Case : ordered list O(n) 1 2 3 4 5 6 7 8 9 10 11 12 13 home
Shell Sort (Donald Shell) typedef int T; //c void shellsort(T a[], int n){ //size = n int j; for(int gap = n/2; gap > 0; gap /= 2 ) for(int i = gap; i < n; i++){ T tmp = a[ i ]; for(j = i; j >= gap && tmp < a[j-gap]; j -= gap) a[j] = a[j-gap]; a[j] = tmp; } popular (but poor) increment (suggested by Shell) ht = n/2 hk = h k+1/2 การเลือก increment สำคัญต่อ performance มาก Sedgewick ได้เสนอ increment sequence ที่ดีไว้หลายอัน หนึ่งในนั่นคือ 1, 5, 19, 41, 109, . . . คือ term ในรูป 9 * 4i - 9 * 2i + 1 หรือ 4i – 3 * 2i + 1 ในทางปฏิบัติ performance เป็นที่ยอมรับได้ แม้ว่า n จะมีค่ามากเป็นหมื่นก็ตาม Donald Shell
Binary Heap Complelete Binary Tree home
Review : Complete BinaryTree H = log2 (N+1) –1 = ⌊ log2N ⌋ → O( log2(N)) N ระหว่าง [2H, 2H+1 – 1] 2 3 4 5 6 7 9 8 10 12 1 2 1 3 4 5 6 7 8 9 10 11 12 11 Complete Binary Tree Every level is completely filled, except possibly the last, & All nodes are as far left as possible Without node 11 : Not a complete binary tree
Ascending heap (Min heap) Decending heap (Max heap) Binary Heap Ascending heap (Min heap) 1 4 3 7 8 9 2 6 5 21 13 31 24 65 26 32 16 68 19 1 4 3 7 8 9 2 6 5 37 92 12 33 25 10 11 86 57 48 Decending heap (Max heap) Binary Heap : complete Binary Tree ซึ่ง key ของ node ใดๆ 1. <= key ของ decendents ของ มัน : Min heap เช่น 13 น้อยกว่าลูกหลานทั้งหมดของมัน 2. >= key ของ decendents ของ มัน : Max heap เช่น 37 มากกว่าลูกหลานทั้งหมดของมัน Not a heap 21 13 31 6 65 26 32 16 68 19 home
Review : (Sequential) Implicit Array O G A C L M F J K E H I D B N O G A C L M F J K E H I D B 13 14 6 2 11 12 5 9 10 4 7 8 3 1 14 15 7 1 3 12 13 6 10 11 5 8 9 4 2 A B C D E F G H I J K L M N O 1 2 3 4 5 6 7 8 9 10 11 12 13 14 A B C D E F G H I J K L M N O 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 G A C L M F I D B G A C L M F I D B 13 14 6 2 11 12 5 9 10 4 7 8 3 1 14 15 7 1 3 12 13 6 10 11 5 8 9 4 2 A B C D F G I L M 1 2 3 4 5 6 7 8 9 10 11 12 13 14 A B C D F G I L M 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Insert Heap Insert 14 heap size’s increasing by 1 14 14 13 21 16 24 31 5 4 8 9 10 3 7 6 n 21 13 24 65 26 32 16 68 19 31 1 4 3 7 8 9 2 6 5 2 1 5 4 8 9 10 3 7 6 21 16 Perlocate 14 up 24 31 19 68 14 Perlocate 14 up n 65 26 32 14 13 21 16 24 31 19 68 65 26 32 13 21 16 24 31 19 68 65 26 32 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 heap heap found 14’s right place 14 13 21 24 65 26 32 16 68 19 31 2 1 5 4 8 9 10 3 7 6 n Inserting 14. ก่อนจะ insert : last index = n-1 (data 32) insert จะเพิ่มขนาด heap ขึ้น 1 ที่ตำแหน่ง n พยามหาที่ให้ 14 เริ่มลองที่ n ถ้าไม่ได้ perlocate 14 up (14<31) (14<พ่อ), เลื่อนพ่อของมัน (31) down Repeat พยามหาที่ให้ 14 ตาม path ไปยัง root จนกว่าจะพบที่ของ 14 After Insertion ขนาด heap เพิ่มขึ้น 1 การปรับ tree ให้เป็น heap อีกครั้งเรียกการ reheap 13 14 16 24 21 19 68 65 26 32 31 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 11 heap size’s increasing by 1
Insert Heap : to create heap 13 13 1 4 3 7 8 9 2 6 5 n 1 4 3 7 8 9 2 6 5 n 2 1 5 4 8 9 10 3 7 6 n 21 16 2 1 5 4 8 9 10 3 7 6 n 21 16 Perlocate 14 up 24 31 19 68 24 14 19 68 65 26 32 14 65 26 32 31 Perlocate(reheap) 14 up 13 21 16 24 31 19 68 65 26 32 13 21 16 24 31 19 68 65 26 32 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 heap heap 13 Inserting 14. //heap size = n Increasing node must be at n. 14 (<31(14’s father)) cannot be at n, perlocate 14 up, 31 goes down at n. Repeat perlocating 14 up to find its right place. Then heap size is 1 increasing ie. n+1 Adjusting the tree to be heap again is called reheap. 1 4 3 7 8 9 2 6 5 n 2 1 5 4 8 9 10 3 7 6 n 14 16 found 14’s right place 24 21 19 68 65 26 32 31 13 14 16 24 21 19 68 65 26 32 31 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 11 heap size’s increasing by 1
Delete Min (ie. Delete root) : to sort data 14 21 20 65 26 32 16 68 19 31 2 1 5 4 8 9 10 3 7 6 11 temp 13 Delete 13 31 ? 13 temp 13 Start at min heap from index : 0 to 10 Delete min (root 13) -> hole at root. To delete, heap size shorter 1 (last node) Last node data,31, must be in the heap. Find place for 31(reheap).Try the hole. if not, perlocate 31 down, take the hole’s smaller son up. Repeat finding place for 31. Put the deleting data 13 at previous-31- place in the same array is called in place sort, makes decending order. Now 13 is out of heap. 1 4 3 7 8 9 2 6 5 10 31 ? 2 1 5 4 8 9 10 3 7 6 11 14 16 20 21 19 68 65 26 32 31 13 14 16 20 21 19 68 65 26 32 31 this slot is out of heap 0 1 2 3 4 5 6 7 8 9 10 Delete Min = c log2 n Delete min n times. Heap sort -> O(n log2 n) heap size shorter =1 20 14 21 26 65 31 32 16 68 19 13 2 1 5 4 8 9 10 3 7 6 11 temp Delete 13 20 14 21 65 26 32 16 68 19 31 31 ? 2 1 5 4 8 9 10 3 7 6 11 temp 13 Delete 13 20 14 21 26 65 32 16 68 19 31 2 1 5 4 8 9 10 3 7 6 11 temp 13 Delete 13 14 20 16 26 21 19 68 65 31 32 13 0 1 2 3 4 5 6 7 8 9 10 heap size shorter =1
Heap Sort Analysis Delete 13 Delete 13 Delete 13 31 ? 13 13 13 31 ? 14 21 20 65 26 32 16 68 19 31 31 ? 2 1 5 4 8 9 10 3 7 6 11 temp 13 Delete 13 14 21 20 65 26 32 16 68 19 31 31 ? 2 1 5 4 8 9 10 3 7 6 11 temp 13 Delete 13 20 14 21 65 26 32 16 68 19 31 31 ? 2 1 5 4 8 9 10 3 7 6 11 temp 13 Delete 13 ไม่ดีเมื่อ n น้อย (ต้องเสียเวลาในการปรับให้เป็น heap) Maximum delete min 1 ตัว = O(log2n) เพราะ depth ของ heap เป็น log2n ดังนั้น Heap Sort = deleteMin n-1 ครั้ง = O(n log2n) ใช้ space น้อยมาก แทบไม่มี extra space เลย หากทำ inplace sort avg case ดีไม่เท่า avg case ของ quick sort แต่ worst case แย่กว่า avg case ของ quick sort นิดเดียว (worst case ของ quick sort = O(n2) ) จากการศึกษาพบว่าโดยทั่วไป heap sort กินเวลาประมาณ 2 เท่าของ quick sort ในทางปฏิบัติพบว่าช้ากว่า Shell Sort ที่ใช้ incremental suquence ของ Sedgewick
Merge Sort #comparisions = ____ #assignments = ____ Merge = O(___) 5 3 6 1 2 7 8 4 8=23 4=22 2=21 1=20 merge d = ? merge #comparisions = ____ #assignments = ____ Merge = O(___) merge Key idea : Merge : sorts successive pair to be sorted bigger one. Merge size 1 successive pair → sorted size 2 Merge size 2 successive pair → sorted size 4 Merge size 4 successive pair → sorted size 8 1 3 5 6 2 4 7 8 a b c 1 2 home
Merge Sort #comparisions <=n # assignments = n Merge = O(n) 5 3 6 1 2 7 8 4 8=23 4=22 2=21 1=20 merge O(n) d n=2d d=log2n merge O(n) merge O(n) #comparisions <=n # assignments = n Merge = O(n) mergeSort = merge O(N) *d = N*log2N 1 3 5 6 2 4 7 8 a b c
Merge Sort Pseudocode Merge //mergeSort : sort a from left to right mergeSort(a, left, right) T(1) = 1 if (left < right) T(N) = 2 * T(N/2) + N center = (left + right) / 2 mergeSort(a, left, center) → T(N/2) mergeSort(a, center+1, right ) → T(N/2) merge(a,left,center,center+1,right) → N 5 3 6 1 2 7 8 4 left right center //mergeing ordered a [iA,endA] & b [iB,endB] //to be ordered using temp_list C [iA,endB] Merge(a, iA, endA, iB, endB) c = C[iA] loop(iA < endA and iB < endB) if ((a[iA] < a[iB]) C[c] = a[iA], iA++ else C[c] = a[iB], iB++ c++ appending C with the remaining list copy C back to a Merge # comparisions = <N # assignments = N O( N ) A 1 3 5 6 B 2 4 7 8 a b C c
Merge Sort Analysis : Telescoping a sum T(N) = 2*T(N/2) + N ....(2) 5 3 6 1 2 7 8 4 T(N) = 2*T(N/2) + N ....(3):(2)/N N N N log2n T(N) = T(N/2) + 1 .....(*):(from 3) N N/2 T(N/2) = T(N/4) + 1 .....(*):any N=2i N/2 N/4 T(N/4) = T(N/8) + 1 .....(*) ,, N/4 N/8 . . . T(2) = T(1) + 1 .....(*) ,, 2 1 Merge A 1 3 5 6 B 2 4 7 8 a b C c 1 (from (1)) T(N) = T(1) + 1*log2N //sum* = Telescoping a Sum N 1 T(N) = N + N*log2N = O(N log N)
Merge Sort Analysis : Brute Force 8=23 4=22 2=21 1=20 5 3 6 1 2 7 8 4 T(1) = 1 ...(1) T(N)= 2*T(N/2)+N ...(2) merge O(N) T(N)= 2*(2*T(N/4)+N/2)+N T(N)= 4*T(N/4)+2N d n=2d d=log2n merge O(N) T(N)= 4(2*T(N/8)+N/4)+2N T(N)= 8*T(N/8)+3N merge O(N) mergeSort = merge O(N) *d = N*log2N T(N)= 16*T(N/16)+4N .... T(N)= 2d*T(N/2d)+dN ...(3) Merge 1 A 1 3 5 6 B 2 4 7 8 a b C c T(N)= N + log2N*N :d=log2n, n=2d T(N)= O(N log N)
merge Merge Sort Code a 5 3 6 1 2 7 8 4 tArr template <class T> void mergeSort(T* a,T* tArr,int left,int right){ int center = (left+right)/2; if (left < right){ mergeSort(a,tArr,left,center); mergeSort(a,tArr,center+1,right); //merging:merge left&right sorted halfs //of array a to be sorted in tArr //then copy tArr back to a merge(a,tArr,left,center+1,right); } a tArr merge a 1 3 5 6 2 4 7 8 a b tArr c
template <class T> Merge Code template <class T> void merge(T* a,T* tArr,int left,int right,int rEnd){ int lEnd = right - 1; int i = left; //index to put data in tArr while (left <= leftEnd && right <= rEnd) if (a[left] < a[right]) tArr[i++] = a[left++]; else tArr[i++] = a[right++]; //copy the rest of left half if any while (left <= leftEnd) //copy the rest of right half if any while (right <= rEnd) tArr[i++] = a[right++]; for (int i = 0; i <= rEnd; i++)//copy tArr back to a a[i] = tArr[i]; } Merge 1 3 5 6 2 4 7 leftEnd rEnd i
2. Partition : Pivot partitions files into 2 halves Quick Sort Key idea : Choose the pivot 1st element median of 3 average 1 2 3 4 5 6 7 8 9 pivot 3 1 4 2 5 8 6 7 9 2. Partition : Pivot partitions files into 2 halves Ordered List pivot’s right place pivot Left half < pivot Right half > pivot Left half < pivot Right half > pivot Pivot goes to its right place 1 2 3 4 5 6 7 8 9 3. Repeat partitioning both left & right half home
Quick Sort Partition : 1st element //sort a[left,right] QuickSort(a, left, right) if a’s size > 1 pivot = first element i = index of second element j = index of last element; loop(i < j) right scan i until element > pivot left scan j until element < pivot if(i < j) swap elements at i and j //if i > j means all list is scaned swap pivot to right pos at j QuickSort left half a[left,j-1] QuickSort right half a[j+1,right] 1 2 3 4 5 6 7 8 9 i j pivot 5 1 4 6 3 8 2 7 9 i j 5 1 4 2 3 8 6 7 9 i j j < i Stop, pivot’s place is at j 3 1 4 2 5 8 6 7 9 Left part < pivot Right part > pivot pivot’s right place 1 2 3 4 5 6 7 8 9 Ordered List
Quick Sort C++ Code : 1st element template <class T> void quick(T* a, int left, int right){ if (left < right){ int pivot = a[left], i = left, j = right+1; while(i < j){ while(i+1 <= right && a[++i] <= pivot) ; while(j-1 >= left && a[--j] >= pivot) if(i < j){ //swap elements at i and j int t = a[i]; a[i] = a[j]; a[j] = t; } } //while if (left != j){ //swap pivot to the right position j a[left] = a[j]; a[j] = pivot; quick(a, left, j-1); quick(a, j+1, right);
Recursion of Quicksort quick sort[0,9], pivot=5 0 1 2 3 4 5 6 7 8 9 [5 1 4 9 6 3 8 2 7 0] i j i,j=3,9 swap(9,0) [5 1 4 0 6 3 8 2 7 9] i j i,j=4,7 swap(6,2) [5 1 4 0 2 3 8 6 7 9] j i i,j=6,5 pvPos=5 swap(5,3) [3 1 4 0 2 5 8 6 7 9] quick sort[0,4], pivot=3 0 1 2 3 4 [3 1 4 0 2] i j i,j=2,4 swap(4,2) [3 1 2 0 4] j i i,j=4,3 pvPos=3 swap(3,0) [0 1 2 3 4] quick sort[0,2], pivot=0 0 1 2 [0 1 2] j i i,j=1,0 pvPos=0 Recursion of Quicksort quick sort[1,2], pivot=1 1 2 [ 1 2] j i i,j=2,1 pvPos=1 quick sort[6,9], pivot=8 6 7 8 9 [ 8 6 7 9] j i i,j=9,8 pvPos=8 swap(8,7) [ 7 6 8 9] quick sort[6,7], pivot=7 6 7 [ 7 6] j i i,j=7,7 pvPos=7 swap(7,6) [ 6 7] [0 1 2 3 4 5 6 7 8 9]
Quick Sort Partition : Median of Three 1 1 2 3 4 5 6 7 8 9 left center right 8 6 Median = 6 = pivot left center right 8 1 4 9 3 5 2 7 6 i j j 2 1 4 9 3 5 8 7 6 i i j j 2 1 4 5 3 9 8 7 6 i j i j 2 1 4 5 3 6 8 7 9 Left part < 6 j < i Stop, pivot’s place is at i Right part > 6 pivot’s right place 1 2 3 4 5 6 7 8 9 Ordered List
Quick Sort Partition : Median of Three : version 2 1 2 3 4 5 6 7 8 9 left center right 1 4 9 6 3 5 2 7 8 median of three(left,center,right) make data in 3 pos. order place pivot in pos. right-1 1 4 9 7 3 5 2 6 8 pivot i j 1 4 2 7 3 5 9 6 8 i j 1 4 2 5 3 7 9 6 8 i j 1 4 2 5 3 6 9 7 8 Left part < 6 j < i Stop, pivot’s place is at i Right part > 6 1 2 3 4 5 6 7 8 9 pivot’s right place Ordered List
Quick Sort (Previous Algorithm) template <class T> void quicksort(vector<T> & a, int left,int right){ if( left + 10 <= right ) { T pivot = median3(a,left,right); //make data in 3 pos. Order //place pivot in pos. right - 1 //Begin partitioning int i = left, j = right-1; for( ; ; ){ while( a[++i] < pivot ) { } while( pivot < a[--j] ) { } if( i < j ) swap(a[i],a[j]); else break; } //for //restore pivot swap(a[i],a[right-1]); quicksort(a,left,i-1); quicksort(a,i+1,right); } //if else // sort small size data insertionSort(a, left,right); }
แต่ละ pass compare n ครั้ง ขึ้นกับ pivot เป็นอย่างไร Quick Sort Analysis แต่ละ pass compare n ครั้ง ขึ้นกับ pivot เป็นอย่างไร Best Case แบ่งได้ 1/2 ทุกครั้ง n n/2 n/4 100 50 1 1 1 . . . 1 1 1 20 21 2d T(N) = 2 T(N/2) + cN T(N) = cN log N + N = O(N log N) 100 ตัว => 2d = n => d = log2n Worst Case = n + (n-1) + (n-2) + ... + 1 = O(n2) T(N) = T(N-1) + cN T(N-1) = T(N-2) + c(N-1) T(N-2) = T(N-3) + c(N-2) … T(2) = T(1) + c(2) n T(N) = T(1) + c∑i = Ө(N2) i=2 n n-1 n-2 n--3 n-3 Average Case ~ 1.386 n log2n