本肥宅開始自己的刷題之路了,作為第一個目標,我選擇了快速排序。
講完快排沒有多長時間,老師也是一筆帶過,又碰巧在洛谷上發現了這道題,碰巧作下,就醬紫~
快排挺好玩的,原理也很簡單:在待排的數據中隨機挑選一個數據作為關鍵數據(用key代替),然后,小的放在key前,大的放在key后,再分別對 “小的一段” 和 “大的一段” 進行快排就可以了~
1 #include <iostream> 2 3 using namespace std; 4 5 int N, a[100001]; 6 void swap (int& a, int& b); 7 void qSort (int front = 1,int rear = N); 8 int main(){ 9 cin >> N; 10 for (int i = 1;i <= N;i++) 11 cin >> a[i]; 12 qSort(); 13 for (int i = 1;i <= N;i++) 14 cout << a[i] <<' '; 15 system("PAUSE"); 16 return 0; 17 } 18 19 void swap (int& a, int& b){ 20 int c = a; 21 a = b; 22 b = c; 23 } 24 25 void qSort (int front,int rear){ 26 if (front >= rear) 27 return; 28 swap(a[front], a[(front + rear)/2]); 29 int i = front,j = rear,k = a[front]; 30 while (i < j){ 31 while (a[j] > k&&i < j) j--; 32 a[i++] = a[j]; 33 while (a[i] < k&&i < j) i++; 34 a[j--] = a[i]; 35 } 36 a[(i+j+1)/2] = k; 37 qSort(front, (i+j+1)/2-1); 38 qSort((i+j+1)/2+1, rear); 39 }
但是呢,排序的時候可不是單純的隨機挑選 key ,再創建一個數組,把原來要排序的數組掃描進去。這樣很麻煩的。
本文代碼中,在 qSort 函數中選擇 i , j 兩個變量,分別從頭、尾進行掃描,我這里每次選擇待排序數組 a 中的第一個數作為 key ,然后呢,我選擇先從尾部進行掃描(這時的 a[front] 的值已經被存儲)(所以 front 位置的數值就沒用嘍~)將發現的第一個比 key 小的值放到 front 位置(同理,這時 j 位置的數值就沒用了)(而且 i 的位置就放上了比 key 小的數字,i自然就要++啦~)然后等到它慢慢循環到 i == j(大霧)就結束這一部分了。
最后就是尋找 key 應該住的位置,把它正位,再遞歸 qSort() 就完成了!~
什么?還有 swap(a[front], a[(front + rear)/2]); ?當然是為了防止 oj 用升序或者降序的測試點卡我啦,hhhh~
