1. 程式人生 > >快速排序的實現與註意點

快速排序的實現與註意點

while c++代碼 16px ret color int main srand 為什麽

先上實現了的C++代碼:

 1 #include  <ctime>
 2 #include  <cstdio>
 3 #include  <cstdlib>
 4 #include  <iostream>
 5 using namespace std;
 6 const int maxn = 100;
 7 int a[maxn], n;
 8 void quick_sort(int left, int right) {
 9     if(left > right) {
10         return;
11     }
12     int
i = left, j = right, key = a[left]; 13 while(i != j) { 14 while(i < j && a[j] >= key) { 15 j--; 16 } 17 //尋找分界點右邊比key小的數 18 while(i < j && a[i] <= key) { 19 i++; 20 } 21 //尋找分界點左邊比key大的數 22 if
(i != j) { 23 swap(a[i], a[j]); 24 } 25 //如果找到了,則交換 26 } 27 swap(a[left], a[i]); 28 //將key放到分界點的位置上,之後進行遞歸處理分界點兩側的數據 29 quick_sort(left, i - 1); 30 quick_sort(i + 1, right); 31 } 32 int main() { 33 scanf("%d", &n); 34 srand((unsigned)time(NULL));
35 for(int i = 0; i < n; i++) { 36 a[i] = rand() % 1000; 37 } 38 quick_sort(0, n - 1); 39 for(int i = 0; i < n; i++) { 40 printf("%d ", a[i]); 41 } 42 printf("\n"); 43 return 0; 44 }

下邊說說兩個註意點:

(1)關於quick_sort函數第一句,為什麽要判斷left是否大於right?

考慮這樣一組輸入數據:

10
279 786 373 946 460 552 698 754 519 759
這組數據就是為什麽要有if(left > right)的原因,因為第一輪下來以後,i、j均為0(279比其他所有數都小),之後遞歸處理的時候,左邊的區間為(0, -1),不合法!

(2)為什麽每一輪查找左右兩部分的時候,都要從右端開始(下標j)?
每一輪兩邊找的時候,都從右邊開始的原因是為了保證最終a[i]和a[left]交換的時候,a[i]>=a[left]
比如考慮這樣一組數據:
6
7 1 2 3 4 8
這樣如果從左邊先找,第一輪下來後,將會使得i為5,交換a[0]和a[5],左邊區間為0-4,右邊沒有,但是左邊區間有一個8,比7大!

快速排序的實現與註意點