排序 快速排序

2021-06-26 07:28:51 字數 2397 閱讀 2345

快速排序時實踐中最快的一直排序,平均時間是0(nlogn),最壞的情況是o(n2)但是很容易將這種情況避免

空間複雜度:o(n*lgn),

不穩定。

快速排序時基於分治模式處理的,

對乙個典型子陣列a[p...r]排序的分治過程為三個步驟:

1.分解:

a[p..r]被劃分為倆個(可能空)的子陣列a[p ..q-1]和a[q+1 ..r],使得

a[p ..q-1] <= a[q] <= a[q+1 ..r]

2.解決:通過遞迴呼叫快速排序,對子陣列a[p ..q-1]和a[q+1 ..r]排序。

3.合併。

主要思想是選擇乙個pivot,將小於和大於他的資料分為兩個集合,使用遞迴的處理方式得到最後的排序

選擇樞紐元:

選擇樞紐元將影響排序的時間複雜度,錯誤的方式是選擇第乙個元素作為樞紐元,但是如果是逆序的情況,這將變得十分糟糕,一種安全的做法是隨機選擇樞紐元,但是隨機數的生成一般是比較昂貴的

我們選擇一種三數中值分割法:

將序列中的左端,右端,中間的資料進行比較,選擇出來中間的資料作為樞紐元,同時完成他們的排序工作,左端是三者中的最小值,右端是三者中的最大值

問題:

在真正的過程中我們遇到乙個問題,就是如果元素和樞紐元相等,是否對其進行交換

考慮都是相等數的情況,如果i,j都停止,交換沒有意義,但是可以讓i,j在中間交錯,總時間為o(nlohn),產生兩個幾乎相等的子陣列

如果i,j不停止,防止i,j越出陣列的界限,最後樞紐元將交換到i最後到過的位置,產生兩個非常不均衡的陣列

因此我們選擇在遇到相同元素的時候讓i,j停下來,準備交換

小陣列:對於很小的陣列,快速排序不如插入排序好,因此我們將插入排序融入演算法當中(具體實現)

小技巧:

由於之前的三數中值讓左端,右端資料已經有序,所以i,j分別初始化為left+1,right-2,這樣可以大大防止溢位

#include using namespace :: std;

void swap(int & a,int &b)

int median3(int *a, int left, int right)

if (a[left] > a[right])

if (a[center] > a[right])

swap(a[center],a[right-1]);//a[center] is pivot,hide it

return a[right-1];//return pivot

}void insertionsort(int *a,int n)

a[j] = tmp; }}

#define cutoff 3

void qsort(int *a,int left,int right)

if (i < j)

else

}swap(a[i],a[right-1]); //restore the pivot

qsort(a,left,i-1);

qsort(a,i+1,right);

} else }

void quicksort(int * a,int n)

void main()

; quicksort(a,10);

for (int i = 0; i < 10; i++)

}

不進行遞迴的實現方法:

#include#includeusing namespace std;

int partition(int array,int lhs,int rhs)

} swap(array[i+1],array[rhs]);

return i+1;

}void quicksort(int *arr,int left,int right)

if(mid+1 < right)

while(!st.empty())

if(mid+1 < q)

} }else

return;

}int main()

; for(int i=0;i<10;i++)

cout

//演算法導論上的實現 ,quicksort_1

int partition(int array,int lhs,int rhs)

} std::swap(array[i+1],array[rhs]);

return i+1;

} void quicksort_1(int array,int lhs,int rhs) }

int main()

; for(int i=0;i<10;i++)

cout<

排序 快速排序

定義 在快速排序演算法中,使用了分治策略,將要排序的序列分成兩個子串行,然後遞迴地對子序列進行排序,直到整個序列排序完畢。步驟 1.在序列中選擇乙個關鍵元素作為軸 2.對序列進行重新排序,將比軸小的元素移到軸的前邊,比軸大的元素移動到軸的後面。在進行劃分之後,軸便在它最終的位置上 3.遞迴地對兩個子...

排序 快速排序

時間複雜度 快速排序每次將待排序陣列分為兩個部分 1 在理想狀況下,每一次都將待排序陣列劃分成等長兩個部分,則需要logn次劃分。2 在最壞情況下,即陣列已經有序或大致有序的情況下,每次劃分只能減少乙個元素,快速排序將不幸退化為氣泡排序,最壞情況為o n 2 快速排序的平均時間複雜度為o nlogn...

排序 快速排序

高快省的排序演算法 有沒有既不浪費空間又可以快一點的排序演算法呢?那就是 快速排序 啦!光聽這個名字是不是就覺得很高階呢。假設我們現在對 6 1 2 7 9 3 4 5 10 8 這個10個數進行排序。首先在這個序列中隨便找乙個數作為基準數 不要被這個名詞嚇到了,就是乙個用來參照的數,待會你就知道它...