核心代碼如下:
int partition(int a[],int left,int right){
?????? srand((unsigned)time(NULL));
?????? int p=(round(1.0*rand()/RAND_MAX*(right-left))+left);? ? //選擇軸元素
?????? swap(a[left],a[p]);? ??
?????? int temp=a[left];? ?//將軸元素存放至臨時變量temp
?????? while(left<right){? ? //只要left和right不相遇
????????????? while(left<right && a[right]>temp) right--;? ? //反復左移right
????????????? a[left]=a[right];
????????????? while(left<right && a[left]<=temp) left++;? ? //反復右移left
????????????? a[right]=a[left];
?????? }
?????? a[left]=temp;? //把temp放到left與right相遇的地方
?????? return left;? //返回相遇的下標
}
void quickSort(int a[],int left,int right){
?????? if(left<right){
????????????? int pos=partition(a,left,right);? //將a[left,right]一分為二
????????????? quickSort(a,left,pos-1);? //對左子區(qū)間遞歸進行快速排序
????????????? quickSort(a,pos+1,right);? //對右子區(qū)間遞歸進行快速排序
?????? }
}
?????? 快速排序的核心思想在于每次選擇一個軸绍昂,根據(jù)這個軸進行排序梳虽,比軸小的元素放在軸的左側,比軸大的元素放在軸的右側,當左右指針相遇時為排序邊界力崇,其思想理解起來很容易,在具體實現(xiàn)時有以下需要注意的地方馒胆。
??? (1)隨機數(shù)的生成热康。先用rand()函數(shù)生成一個[0,RAND_MAX]范圍內的隨機數(shù),然后再用這個隨機數(shù)除以RAND_MAX蚕脏,這樣就會得到一個[0,1]范圍內的浮點數(shù)侦副。我們只需要用這個浮點數(shù)乘以(right-left),再加上left即可驼鞭,即(round(1.0*rand()/RAND_MAX*(right-left))+left)秦驯,相當于這個浮點數(shù)就是[left,right]范圍內的比例位置。
??? (2)每次選擇軸時最好是利用隨機數(shù)隨機選擇挣棕,而不是適中使用最左側元素作為軸译隘,這是因為當始終使用最左側元素作為軸時,可能會導致算法的最壞時間復雜度達到洛心。但采用隨機數(shù)生成軸時算法對于任意輸入數(shù)據(jù)的時間復雜度都能達到
固耘。
??? (3)兩側指針在進行移動時采用分批連續(xù)移動的方法,如上述代碼所示词身。先從右側開始厅目,判斷當前元素是否大于軸元素,若大于則持續(xù)左移法严,直至遇到第一個小于等于軸元素的數(shù)损敷,然后將該元素與左側指針所指的數(shù)進行交換;然后從左側開始看深啤,判斷當前元素是否小于等于軸元素拗馒,若小于等于則持續(xù)右移,直至遇到第一個大于軸元素的數(shù)溯街,然后將該元素與右側指針所指的數(shù)交換诱桂;再從右邊看….直至左右指針重合為止。
??? (4)具體排序的時候就直接遞歸調用呈昔,不斷地選擇軸元素挥等、分塊,最后達到有序的狀態(tài)堤尾。