//參考文章:
#include
#include
/*隨機找出乙個數(通常就拿陣列第乙個資料就行),
把它插入乙個位置,使得它左邊的數都比它小,它右邊的資料都比它大,這樣就將乙個陣列分成了兩個子陣列,
然後再按照同樣的方法把子陣列再分成更小的子陣列,直到不能分解為止。 它也是分治思想的乙個經典實驗(歸併排序也是)
舉例說明:
假設我們現在對「6 1 2 7 9 3 4 5 10 8」這個10個數進行排序。首先在這個序列中隨便找乙個數作為基準數,
為了方便,就讓第乙個數6作為基準數吧。接下來,需要將這個序列中所有比基準數大的數放在6的右邊,比基準數小的數放在6的左邊;
分別從初始序列「6 1 2 7 9 3 4 5 10 8」兩端開始「探測」。先從右往左找乙個小於6的數,再從左往右找乙個大於6的數,然後交換他們。
這裡可以用兩個變數i和j,分別指向序列最左邊和最右邊。我們為這兩個變數起個好聽的名字「哨兵i」和「哨兵j」。
剛開始的時候讓哨兵i指向序列的最左邊(即i=1),指向數字6。讓哨兵j指向序列的最右邊(即j=10),指向數字8。
首先哨兵j開始出動。因為此處設定的基準數是最左邊的數,所以需要讓哨兵j先出動,這一點非常重要(請自己想一想為什麼)。
哨兵j一步一步地向左挪動(即j--),直到找到乙個小於6的數停下來。接下來哨兵i再一步一步向右挪動(即i++),直到找到乙個數大於6的數停下來。
最後哨兵j停在了數字5面前,哨兵i停在了數字7面前;
現在交換哨兵i和哨兵j所指向的元素的值。交換之後的序列如下。
6 1 2 5 9 3 4 7 10 8
到此,第一次交換結束。接下來開始哨兵j繼續向左挪動(再友情提醒,每次必須是哨兵j先出發)。他發現了4(比基準數6要小,滿足要求)之後停了下來。
哨兵i也繼續向右挪動的,他發現了9(比基準數6要大,滿足要求)之後停了下來。此時再次進行交換,交換之後的序列如下。
6 1 2 5 4 3 9 7 10 8
第二次交換結束,「探測」繼續。哨兵j繼續向左挪動,他發現了3(比基準數6要小,滿足要求)之後又停了下來。
哨兵i繼續向右移動,糟啦!此時哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。說明此時「探測」結束。我們將基準數6和3進行交換。交換之後的序列如下。
3 1 2 5 4 6 9 7 10 8
這樣,就可以以6作為分割點,將陣列分成了兩部分,再對這兩部分進行相同的操作,知道陣列不可分割為止;
思考:為什麼每次必須是哨兵j先出發?
因為當哨兵相遇時,基準數將和哨兵所在的元素交換位置,哨兵j先出發找到乙個比基準數小的元素可以保證交換後基準數左半部分必然是比基準數小的;
若哨兵i先出發,則有可能造成哨兵相遇時所在的元素其實時比基準數大的,交換後產生錯誤的分割
*/int main()
return 0;
}void quicksort(int * array, int low, int high)//快排函式
int partition(int * array, int i, int j)//陣列分割函式,返回分割點的下標
while(array[i] <= array[m])//從前往後找,尋找乙個比基準數大的陣列元素
temp = array[j];//哨兵所在的元素交換
array[j] = array[i];
array[i] = temp;
}//哨兵相遇,探測結束,結束迴圈
array[m] = array[i];//將基準數與哨兵所在元素交換,作為分割點
array[i] = k;
return i;//返回分割點(基準數)的下標
快速排序演算法C語言
快排的核心思想是分而治之,即第一步先選乙個參考數,第二步將小於參考數的數放左邊,大於該參考數的數放右邊,第三步分別對左邊部分的數和右邊部分的數再進行快排遞迴呼叫。c語言 include void quick sort int a,int p,int r int partition int a,int...
c語言快速排序演算法
每次排序的時候設定乙個基準點,將小於等於基準點的數全部放到基準點的左邊,將大於等於基準點的數全部放到基準點的右邊。includevoid quicksort int a,int left,int right int temp a left temp就是基準 int i left int j righ...
快速排序演算法 C語言
快速排序演算法 c語言 include include void display int array,int high printf n int fast sort int array,int i,int j 迴圈結束,若iif i 隊首元素大於基準資料則繼續迴圈 while i key 迴圈結束,...