快速排序法又稱分割交換排序法, 是目前公認最佳的排序法. 它的原理和氣泡排序法一樣都是用交換的方式. 不過它會先在資料中找到一個虛擬的中間值, 把小於中間值的資料放在左邊而大於中間值的資料放在右邊, 再以同樣的方式分別處理左右兩邊的資料, 直到完成為止.
演算法說明 :
假設有 n 筆紀錄 R1, R2...Rn, 其鍵值為 k1, k2...kn. 快速排序法的步驟如下 :
下面示範快速排序過程, 考慮有資料如右 : 28 6 40 2 63 9 58 16 47 20
第一次比較 : K0=28
第二次比較(1) : K0=9 for [9 6 20 2 16]
第二次比較(2) : K6=58 for [58 63 47 40]
再進行第三次比較可得最後排序結果為 : 2 6 9 16 20 28 40 47 58 63
演算法分析 :
範例代碼 :
- #include
- #include
- using namespace std;
- struct BenchMark {
- int swapTime; // Swap Time
- int verifyTime; // Verify Time
- double cTime; // Consumed Time
- };
- void _swapValue(int *a, int *b) {
- int tmp = *a;
- *a = *b;
- *b = tmp;
- }
- BenchMark quickSort(int data[], int n, int i, int j) {
- BenchMark bm;
- bm.swapTime = 0;
- bm.verifyTime = 0;
- if(i >= j)
- return bm;
- int m=0, left=i+1, right=j;
- int cnt=0, vt=0;
- while(left
- vt++;
- if(data[left]<=data[i]) {
- left++;
- continue;
- }
- vt++;
- if(data[right]>=data[i]) {
- right--;
- continue;
- }
- _swapValue(&data[left], &data[right]);
- cnt++;
- left++;
- right--;
- }
- if(data[i]
- right--;
- }
- _swapValue(&data[i], &data[right]);
- bm.swapTime = cnt+1;
- bm.verifyTime = vt;
- for(int k=0; k
- printf("%2d ", data[k]);
- }
- printf(" (k=%d: left=%d, right=%d)\n",right, i, j);
- BenchMark tmp = quickSort(data, n, i, right-1);
- bm.swapTime+=tmp.swapTime;
- bm.verifyTime+=tmp.verifyTime;
- tmp = quickSort(data, n, right+1, j);
- bm.swapTime+=tmp.swapTime;
- bm.verifyTime+=tmp.verifyTime;
- return bm;
- }
- void _showData(int data[], int size) {
- for(int i=0; i
- printf("%2d ", data[i]);
- }
- printf("\n");
- }
- #define QUICK_DATA_SIZE 10
- void ch08_06(bool b) {
- if(b) {
- int data[QUICK_DATA_SIZE] = {28,6,40,2,63,9,58,16,47,20};
- printf("原始資料為: ");
- _showData(data, QUICK_DATA_SIZE);
- BenchMark bm = quickSort(data, QUICK_DATA_SIZE, 0, QUICK_DATA_SIZE-1);
- cout << "快速排序: " << endl;
- _showData(data, QUICK_DATA_SIZE);
- printf("Swap time: %d\n", bm.swapTime);
- printf("Verify time: %d\n", bm.verifyTime);
- }
- }
Ruby Sample Code:
- alg/sort/SortMod.rb
- alg/sort/QuickSort.rb
- Demo Code
Execution result:
- module SortMod
- @@des_cmp = lambda{ |a,b| return a <=> b}
- @@asc_cmp = lambda{ |a,b| return b <=> a}
- def sort(ary, desc=true)
- nary = []
- ary.each{ |item|; nary << item; }
- csort(nary, desc ? @@des_cmp : @@asc_cmp)
- nary
- end
- def csort(ary, cmp)
- raise RuntimeError, "Muse implement
method!" - end
- def swap(ary, i, j)
- ary[i], ary[j] = ary[j], ary[i]
- end
- def sort?(cmp, desc=true)
- csort(cmp, desc ? @@des_cmp : @@asc_cmp)
- cmp
- end
- end
- require "alg/sort/SortMod"
- class QuickSort
- # http://localhost/jforum/posts/list/962.page
- include SortMod
- def qsort(ary, cmp, h, t)
- if(h+1==t)
- swap(ary, h, t) if cmp.call(ary[h], ary[t])==1
- elsif h
- m=0; left=h+1; right=t
- while left
- if cmp.call(ary[h], ary[left])==1
- left+=1
- next
- end
- if cmp.call(ary[h], ary[right])==-1
- right-=1
- next
- end
- swap(ary, left, right)
- left+=1
- right-=1
- end # while
- right-=1 if cmp.call(ary[h], ary[right]) == -1
- swap(ary, h, right)
- qsort(ary, cmp, h, right-1)
- qsort(ary, cmp, right+1, t)
- end
- ary
- end
- def csort(ary, cmp)
- return qsort(ary, cmp, 0, ary.size-1)
- end
- end
- printf("Quick Sorting Demo:\n")
- qickSort = QuickSort.new
- printf("Original ary: %s\n", a)
- printf("After sort(desc): %s\n", qickSort.sort(a, false))
- printf("After sort(asc) : %s\n", qickSort.sort(a, true))
- printf("Original ary: %s\n\n", a)
沒有留言:
張貼留言