最近在複習資料結構,遇到排序演算法,自然排序演算法效率最高的當然是快速排序,今天我們就一起來講講快速排序。
快速排序主要分為三個步驟:
1)選擇基準數:在待排序的序列中,按照某種方式懸著乙個元素作為基準數。
2:)對基準數兩邊的數進行分組。把比基準數小的數放在基準數的左邊,比基準數大的數放在基準數的右邊。(可按照自己的需求來選擇放在基準數的左邊還是基準數的右邊ps:需要公升序還是降序)。
3:)用遞迴的方式來對基準數左右兩邊的數經行再次排序;直到快排完成。
既然知道了快排的基本思想,接下來就是實現快速排序演算法了,按照上述的思想來看,選則基準數是決定了快速排序是否高效的乙個標準,對於分支演算法來說,每次進行分治,若能夠分成兩個等長的子串行是,那麼分治演算法的效率會達到最大,這也是為什麼基準數的選擇是非常重要的乙個原因.所以最理想的基準數選擇就是恰好能夠把待排序序列分成兩個等長的子串行。
方法一:最基本的快排(固定基準數)
思路:取待排序的第乙個或者最後乙個元素作為基準數。下面的演算法是取第乙個元素為基準數
int arr[100];//全域性變數,需要在quicksort函式中用到
int n;//儲存需要排序數字的個數
void quicksort(int start,int end)
temp = arr[start];//temp儲存準基數
i = start;
j = end;
while( i != j)
while (arr[i] <= temp && i < j)
if (i < j)
}if (i == j)
quicksort(start,i - 1);
quicksort(i + 1, end);
}
這樣處理的效果很不好,如果待排序序列已經有序,此時的基準數的選擇就是乙個非常不好的分割,因此每次劃分只能是待排序序列減一,最壞的情況,快排淪為冒泡,在實際中,部分序列有序是非常常見的,所以這樣的快排效率不高。
方法二:隨機基準數
思路:在待排序的序列中選取任意乙個元素作為基準數
#include#include#includeint arr[100];//全域性變數,需要在quicksort函式中用到
int n;//儲存需要排序數字的個數
void randindex(int first,int end)
void quicksort(int start,int end)
randindex(start,end);
printf("%d\n",arr[start]);
temp = arr[start];//temp儲存準基數
i = start;
j = end;
while( i != j)
while (arr[i] <= temp && i < j)
if (i < j)
}if (i == j)
quicksort(start,i - 1);
quicksort(i + 1, end);
}int main()
quicksort(1,n);
for (i = 1; i <= n; i++)
printf("\n");
} getchar();
getchar();
return 0;
}
由於基準數是隨機的,那麼殘生的奮哥也不會是總是會出現差的分割,在整個序列都相等的情況是,是最壞的情況,時間複雜度o(n^2),但是,隨機快排得到的理論最壞的情況可能性僅為1/(2^n)。
第三種:三數取中
雖然第二種放發減少了差的分割機率,但是最壞的情況下複雜度還是o(n^2),所以就有第三種
思路:根據前面的分析我們知道最好的分割結果是將待排序的序列分割成等長的子串行,最好的基準數即為序列的中間值,即2/n;但是,這樣明顯減慢了快速排序的速度,這樣的中值估計法我們可以通過隨機選取三個元素並用他們的中值作為基準數,事實上隨機性 並沒有很大的幫助,因此一般的做法是取最左邊的和最右邊的加上中間位置的中值作為基準數,這種方法消除了與排序輸入不好的情況,並減少了大概14%的比較次數。
比如:待排序序列:1 9 2 8 7 3 6 4 10 5
最左邊為:1 最右邊為:5 中間為:7
將他們排序後,中值為5,即5為基準數。並用和第乙個元素交換,用第乙個元素來儲存基準數
這裡就只提供怎麼楊確定基準數的方法,具體的排序方法可參照第一中方法:
void partintionmedianofthree(int arr,int start,int end)
if (arr[start] > arr[end])
if (arr[mid] > arr[start])
}
以上就是所有的內容了,如有不對,請多多指教。 排序演算法之快速排序
快速排序使用分治法 divide and conquer 策略來把乙個序列 list 分為兩個子串行 sub lists 步驟為 從數列中挑出乙個元素,稱為 基準 pivot 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面 相同的數可以到任一邊 在這個分割槽退出...
排序演算法之快速排序
快速排序入口 public void quicksort int lists 遞迴呼叫該函式。原理 每次從陣列從選乙個標兵 本實現為簡單起見直接選取給定範圍內的第乙個元素為標兵 讓後在給定範圍內進行雙向遍歷,目的是以標兵為分界線,將所有小於標兵值的數字排一邊,將所有大於標兵的數字 放到另一邊。標兵移...
排序演算法之快速排序
快速排序是一種不穩定的排序演算法,它的基本思想是,以某個元素為基準,將所有大於等於它的值放在右邊,小於它的值放在左邊,這樣陣列就被分為兩部分,遞迴對這兩部分進行快速排序,而單個元素我們認為是已經排好序的。這是一種歸併思想,當然在最後一步,合併,我們什麼也沒有做也不用做。每一次排序都有乙個元素被放在正...