有關快速排序的幾點思考

2021-06-06 18:53:10 字數 1912 閱讀 3019

快速排序曾被評為

20世紀十大演算法之一,最很多情況來說都是名副其實的最快的排序演算法。其實思路並不難,但在具體的**實現時會有很多細節容易出錯。也有一些細節如果不加注意會使排序效率意外降低。

大致思路是:從待排序陣列中選出乙個值(一般是隨即選的),對陣列進行分割,把小於軸值的放在左側,大於軸值的放在右側。然後分別對左側陣列和右側陣列繼續進行排序(遞迴進行)。一直進行下去,最後可以得到乙個有序陣列。

快速排序本質上是一種交換排序。我們最熟悉的交換排序可能應該是氣泡排序,但快速排序與氣泡排序最根本的不同是:它採用了分而治之的思想,不再是相鄰的去進行交換。這樣可以提高一些效率。

幾個需要注意的細節:

1.軸值的選擇

最簡單的選擇當然是選擇第乙個或最後乙個值,但這樣有乙個風險,如果陣列原來是正序或逆序的,這樣選擇效率可能會比較低,因為有一側的陣列元素個數是

0,這樣最終其實是乙個乙個元素排的。當然可以用隨機數確定下標,但比較麻煩。一般可以選擇中間下標值。

2.怎麼分割陣列

最直接的方法是:確定軸值後,從左側開始找到第乙個大於軸值的元素,下標為

l。從右側開始找到第乙個小於軸值的元素,下標為

r。然後,直接交換兩個值(l處和

r處的)。交換後繼續向前尋找。

個人認為這樣做比較麻煩,對邊界處理比較麻煩,對軸值也要做處理。很容易出錯。

最常用的方法是:確定軸值後(一般是中間下標處的元素),設定乙個遍歷

t parval=arr[mid]

(即是把軸值存起來)。然後把軸值和陣列最後乙個元素進行交換,這時相當於陣列最後乙個位置是空著的,等著放左側符合條件的元素。然後從陣列左側開始遍歷,找到第乙個大於(也可以找大於等於的,但那樣交換次數會多一些)軸值的元素,其下標為

l,把其放在下標為

r處(有的人實現時會判讀一下l和r

的大小關係,如果

l就r--

。其實沒有必要,不需要對

r做處理,知識多使

arr[r]

和parval

多比較了一次而已)。這時再從下標為

r處往左尋找,找到第乙個小於軸值

parval

的值,放在下標

l處。接著繼續即可。知道l和

r相遇,返回

l。幾位軸值

parval

應該在的位置。

**如下:

//快速排序

#include using namespace std;

#define n 5

遇到兩個值直接交換的

分割函式,得到分界點,左側資料都小於分界點值,右側的均大於

若使用arr[l]<=parval,arr[r]>parval這時對於分割值是最大值或最小值時會排序錯誤。比如5,4,10,3,9

此方法可能會陷入死迴圈,比如5,4,9,5

總之,這種方法需要對分割值做額外的處理,以下這種方式寫肯定是有問題的

//template //int partion(t arr,int left,int right)

//// //交換兩個值

// t temp=arr[l];

// arr[l]=arr[r];

// arr[r]=temp;

// cout<<"haha"//if(lvoid quicksort(t arr,int left,int right)

//輸出陣列內容

template void print(t arr,int size)

{ for(int i=0;i

第乙個分割方法(即直接交換的,一直沒有通過所有測試用例),希望能有高手給知道一下。

注意測試用例的全面性:比如一定要測試那些含有重複元素的陣列、分割值即是最大值或最小值的陣列。很容易發現

bug。

最近的幾點思考

在乙個競爭激烈的領域中,一定要做好定位,找好差異化的東西,差異化突出的東西,就是一家公司的特色。如果你本身在小地方發展,你自己有自己的業務,嚮往大城市的發展,捨棄已有的東西著實可惜,去大地方打拼又得從零開始,為什麼不利用好當前的業務,把業務擴充套件過去呢?也就是說,在嚮往的地方和自己的現在擁有的擅長...

工作的幾點思考

進入公司從一開始就已經有整整乙個半月。這是半個月做了什麼回憶。我真的不能告訴。該公司有沒有認真忙。通常不是乙個特別大的作業。有一點休閒。這一次,我的各種疾病就顯現出來了。玩玩手機。看看網頁,甚至和同事說說笑笑。每天晚上回去更是玩得昏天黑地。從來都不為第二天的事兒擔心。感覺自己不是乙個打工的,倒像是領...

多執行緒快速排序(思考)

在csdn看到的一位牛人實現的多執行緒快排,暫時沒細看,但是感覺有點小問題,他的多執行緒快排並沒有實現我所想要的那種平行計算的結果,我理想中的多執行緒排序 這裡特指快排 應該是類似於mapreduce的分拆和合併,在快排中,分拆是必然 和歸併一樣,基因決定嘛 分拆後的陣列可以形成佇列,按照核心數分給...