在演算法訓練中,快排應該是基礎中的基礎了,直接使用前面介紹的快排,無論是單向迴圈還是雙向迴圈方式,在特定的資料序列下,都有可能出現tle(time limit exceeded)超時,這篇文章對原因和基準值的優化進行驗證和總結。 總結
附錄
快排本身不是一種穩定的演算法,在前面的文章中也提到過,預設的實現中一般直接選取最左或者最右進行,而這種方式之下,如果待排序的序列是已經有序的情況之下,快排的效率直接會惡化到n平方的時間複雜度,相當於排序核心的基準值分割演算法幾乎沒有能起到作用,所以這種情況下出現超時也就可以理解了。這種情況之下,最簡單的方式就是首先進行如下基準值選擇的優化,這種情況就可以直接解決本身已經有序的大量帶排序的演算法的排序問題。
基準值最為簡單的優化方式是可以不改變之前的邏輯,在進行排序之前首先按照某種方式選取乙個,放至基準值選取的位置,與之進行交換,相當於打個補丁,之前的**幾乎不必修改。
使用前文給出的實現示例的情況下,單向迴圈較為簡略,在大量資料的情況下,前者的替換效率整體一般會高一些,但有時也不一定,對於不同的測試用例,單跑一次的效果可能也會不同,可以多試,測測人品。
100
time used: 0.000014s
10000
time used: 0.105468s
100000
time used: 10.499863s
100
time used: 0.000019s
10000
time used: 0.130322s
100000
time used: 12.846300s
選取待排序列的左右的中間值作為基準點,比如示例**可能如下
int key =
(left+right)/2
;int tmp=arr[left]
; arr[left]
=arr[key]
; arr[key]
=tmp;
使用附錄3示例**,執行結果如下所示,可以看到提公升2個數量級到千萬級別的有序序列,執行時間也仍然在毫秒級別0.665毫秒:
100
time used: 0.000005s
10000
time used: 0.000442s
100000
time used: 0.005531s
1000000
time used: 0.059314s
10000000
time used: 0.665215s
選取待排序列的左右的中間值作為基準點,比如示例**可能如下
int key =
rand()
%(right - left)
+ left;
int tmp=arr[left]
; arr[left]
=arr[key]
; arr[key]
=tmp;
使用附錄4的示例**,執行結果如下所示
100
time used: 0.000015s
10000
time used: 0.000635s
100000
time used: 0.007567s
1000000
time used: 0.082657s
10000000
time used: 1.008981s
一般來說,平均而言隨機方式比折半方式效果要好一點。當然針對本文示例中已經完全有序的情況,顯然折半方式更加接近於標準答案,但是不同的測試用例,平均效果而言,應該來說隨機方式還是有其優勢的,不過對於應試這種無聊的思路而言,果斷換效果比較好的方式就可以了。
使用雙向迴圈+基準值的優化+平台整體優化選項的使用,一般來說可以解決tle的問題
#include
#include
#include
#include
intpartition
(int
* arr,
int start,
int end)
} arr[start]
=arr[index]
; arr[index]
=pivot;
return index;
}void
quick_sort
(int
* arr,
int start,
int end)
intmain()
}
#include
#include
#include
#include
intpartition
(int
* arr,
int start,
int end)
} arr[start]
=arr[left]
; arr[left]
=pivot;
return right;
}void
quick_sort
(int
* arr,
int start,
int end)
intmain()
}
#include
#include
#include
#include
intpartition
(int
* arr,
int start,
int end)
} arr[start]
=arr[left]
; arr[left]
=pivot;
return right;
}void
quick_sort
(int
* arr,
int start,
int end)
intmain()
}
#include
#include
#include
#include
intpartition
(int
* arr,
int start,
int end)
} arr[start]
=arr[left]
; arr[left]
=pivot;
return right;
}void
quick_sort
(int
* arr,
int start,
int end)
intmain()
}
python實現快排演算法 python快排演算法詳解
快排是python經典演算法之一。1 下面講解的是什麼是快排和快排的圖示。2 快排是一種解決排序問題的運算方法。3 快排的原理 在陣列中任意選擇乙個數字作為基準,用陣列的資料和基準資料進行比較,比基準數字打的數字的基準數字的右邊,比基準數字小的數字在基準數字的左邊,第一次排序之後分為比基準資料大或比...
演算法基礎 排序 快排
先從數列中取出乙個數作為基準數。分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。再對左右區間重複第二步,直到各區間只有乙個數 public static void quicksort int arr,int left,int right int i left int j ...
快排及優化
快速排序的本質就是選取乙個基準數,通過一次快排把基準數大的都放在基準數的左邊,把比基準數小的放在基準數的右邊,這樣就找到了基準數在陣列中的正確位置。然後可以用遞迴的方式分別對前半部分和後半部分排序,最終實現整體陣列有序。所謂排序的穩定性,就是指在排序過程中,在對某關鍵字排序後會不會改變其他關鍵字的順...