藍橋杯 快速排序
【題目描述 - Problem Description】
排序在各種場合經常被用到。 快速排序是十分常用的高效率的算法。
其思想是:先選一個“標尺”, 用它把整個隊列過一遍篩子, 以保證:其左邊的元素都不大於它,其右邊的元素都不小於它。
這樣,排序問題就被分割為兩個子區間。 再分別對子區間排序就可以了。
下面的代碼是一種實現,請分析並填寫划線部分缺少的代碼。
1 #include <stdio.h> 2 3 void swap(int a[], int i, int j) 4 { 5 int t = a[i]; 6 a[i] = a[j]; 7 a[j] = t; 8 } 9 10 int partition(int a[], int p, int r) 11 { 12 int i = p; 13 int j = r + 1; 14 int x = a[p]; 15 while(1){ 16 while(i<r && a[++i]<x); 17 while(a[--j]>x); 18 if(i>=j) break; 19 swap(a,i,j); 20 } 21 _______________;//填空位置 22 return j; 23 } 24 25 void quicksort(int a[], int p, int r) 26 { 27 if(p<r){ 28 int q = partition(a,p,r); 29 quicksort(a,p,q-1); 30 quicksort(a,q+1,r); 31 } 32 } 33 34 int main() 35 { 36 int i; 37 int a[] = {5,13,6,24,2,8,19,27,6,12,1,17}; 38 int N = 12; 39 40 quicksort(a, 0, N-1); 41 42 for(i=0; i<N; i++) printf("%d ", a[i]); 43 printf("\n"); 44 45 return 0; 46 }
【題解】
快排的思想就是區間整理,實現策略大同小異……
在partition沒有使用賦值實現交換,那么填空部分則不會是直接賦值。
在看循環中的下標,跳過首發元素,那么需要補充的代碼就是將x歸位。(可以通過只是遞歸從輸出看出)
觀察循環結束后的區間狀態:x[<=x,j下標落腳][i下標落腳,>=x]
所以直接交換初始x的位置p,和符合條件的下標j
【最終結果】
swap(a, p, j)