分治法 隨機快速排序

2021-07-02 12:22:00 字數 1623 閱讀 4544

常規快速排序基本思想:

分解-->遞迴求解

以下是我認為最簡潔的快速排序**

void quicksort(int a,int p,int r)

a[p]=a[j]; //至於為什麼要交換a[j]和a[p]因為排序到了最後只剩下a[p]大於或者等於a[j](假如只有2,5此時a[p]=a[j]=2)所以必須要交換

a[j]=x;

printarray(a,9);

return j; //為什麼選擇j而不是i,因為到了i>j的情況時,a[i]肯定大於a[j],選擇a[i]的話肯定會打亂排序的

紅色數字表示分割陣列的基準元素,左邊小於它,右邊大於它。

藍色下劃線表示將要進行排序的元素。

總所周知:快速排序的演算法平均時間為o(nlogn),因為存在最差的情況o(n^2),這時間複雜度只是平均而已,具體到某個例項或許就不是這樣了

為什麼呢?

因為快速排序執行時間與劃分是否對稱有關,假如你的每次劃分都不是很均勻,時間複雜度絕對不可能有o(nlogn),

例如(8,7,6,5,4,3,2,1,0),結果如圖:

這裡可以看出有8次遞迴,並沒有》8log8=7.22,從輸出可見,而且有些遞迴是沒有意義的。

那麼所謂的均勻劃分又是什麼呢?

在某一輪排序時,不是單一只選擇首位做基準(如上述的常規演算法),而是每次基準的選擇都是隨機的,對每個元素而言概率大致相同的。

int partion(int a,int p,int r)

a[p]=a[j]; //至於為什麼要交換a[j]和a[p]因為排序到了最後只剩下a[p]大於或者等於a[j](假如只有2,5此時a[p]=a[j]=2)所以必須要交換

a[j]=x;

printarray(a,9);

return j; //為什麼選擇j而不是i,因為到了i>j的情況時,a[i]肯定大於a[j],選擇a[i]的話肯定會打亂排序的

}

int random(int a,int b)

在這裡我的隨機生成數函式是簡單的取中位數,但確實是有效果的,遞迴規模降低成了7次

然後當我優化一下隨機數生成函式,效果更加明顯,遞迴次數基本上4,5,6左右

看看激動不,當時我就震驚了,時間複雜度竟然可以優化大o(n/2)啊,簡直是超神了。

由此可見快速排序的時間複雜度和劃分程度有很大關係,更重要的是隨機選擇策略的使用,會顯著提高快排的速度。

分治法 快速排序(另外含隨機快速排序)

public class quicksort 快速排序演算法 static void qsort int p,int r a p a j a j x return j public static void main string args system.out.println qsort 0,7 快...

分治法 快速排序

演算法的思想 將大的問題化為小問題 問題性質不變 快速排序是在比較排序中相對較快,所以稱為快速排序。對於乙個陣列a n 快速排序中分界值需要取n次也就是說,每乙個下標對應的值都需要取一次。源 如下 include using namespace std template int partition ...

快速排序,分治法

平均時間複雜度是 o nlogn 在傳入的陣列為倒序時,將出現最壞的情況,時間複雜度為o n 2 private static void myquicksort int arr,int start,int end int divideindex divide arr,start,end 分治法,按d...