排序算法7---快速排序算法
原理:
通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
#include <stdio.h> #define MAXSIZE 9typedef struct {int r[MAXSIZE+1]; //r[0] 作為哨兵int length; //待排序的數組長度 }SqList;void print(SqList L){int i;for(i=1; i<MAXSIZE; i++){printf("%3d,",L.r[i]);}printf("%3d\n",L.r[i]); }void swap(SqList * L, int i, int j){int temp=L->r[i];L->r[i]=L->r[j];L->r[j]=temp; }void QuickSort(SqList * L){void Qsort(SqList * L, int low, int high);Qsort(L,1,L->length); }void Qsort(SqList * L, int low, int high){int Partition(SqList * L,int low, int high);int pivot;//注意在邊界的地方要判斷,pivot=1或者pivot=length,做處理if(low < high){pivot=Partition(L, low, high);//將L->[low-high]一分為二,返回pivotkey所在位置的下標Qsort(L,low,pivot-1);Qsort(L,pivot+1,high);} }int Partition(SqList * L,int low, int high){int pivotkey=L->r[low];while(low < high){while(low < high && L->r[high]>=pivotkey) high--;swap(L,low,high);while(low < high && L->r[low]<=pivotkey) low++;swap(L,low,high);}return low; //返回pivotkey當前的下標 }int main(){SqList L;int num[MAXSIZE+1]={9,7,4,3,2,1,6,5,9,8};for(int i=0; i<10; i++){L.r[i] = num[i];}L.length=9; //快排QuickSort(&L);print(L); return 0; }
時間復雜度
快速排序涉及到遞歸調用,所以該算法的時間復雜度還需要從遞歸算法的復雜度開始說起; 遞歸算法的時間復雜度公式:T[n] = aT[n/b] + f(n) ?;參考之前歸并排序對遞歸算法時間復雜度的計算;最優情況下時間復雜度
此時的時間復雜度公式則為:T[n] = 2T[n/2] + f(n);T[n/2]為平分后的子數組的時間復雜度,f[n] 為平分這個數組時所花的時間; 下面來推算下,在最優的情況下快速排序時間復雜度的計算(用迭代法): ? ? ? ? ? ? ? ? ? ? ? ? ??? T[n] = ?2T[n/2] + n ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ----------------第一次遞歸 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ?? = ?2 { 2 T[n/4] + (n/2) } ?+ n ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ----------------第二次遞歸? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = ?2^2 T[ n/ (2^2) ] + 2n
? ? ??????????????????????????????????? ? ? ? ? ? ? = ?2^2 ?{ ?2 T[n/ (2^3) ] ?+ n/(2^2)} ?+ ?2n ? ? ? ? ? ? ? ? ? ? ? ? ----------------第三次遞歸 ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = ?2^3 T[ ?n/ (2^3) ] ?+ 3n
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? = ?2^m T[1] ?+ mn ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?----------------第m次遞歸(m次后結束),只需要對1個元素的情況進行復雜符分析,即T(1)。
? ? ? ? ? ? ? ?當最后平分的不能再平分時,也就是說把公式一直往下跌倒,到最后得到T[1]時,說明這個公式已經迭代完了(T[1]是常量了)。
? ? ? ? ? ? ? ?得到:T[n/ (2^m) ] ?= ?T[1] ? ?===>> ? n = 2^m ? ====>> m = logn;
? ? ? ? ? ? ? ?T[n] = 2^m T[1] + mn ;其中m = logn;
? ? ? ? ? ? ? ?T[n] = 2^(logn) T[1] + nlogn ?= ?n T[1] + nlogn ?= ?n + nlogn ?;其中n為元素個數
? ? ? ? ? ? ? ?又因為當n >= ?2時:nlogn ?>= ?n ?(也就是logn > 1),所以取后面的 nlogn,即最有情況下的時間復雜度為O(nlogn);(注意:這里logn表示以2為底的n的對數)
?
最差情況下時間復雜度 ? ? ? ? ? ? ? ?? 這種情況時間復雜度就好計算了,就是冒泡排序的時間復雜度:T[n] = n * (n-1) = n^2 + n;
?
??? 平均時間復雜度 ? ?
? ? ? ?快速排序的平均時間復雜度也是:O(nlogn)。 平均的情況,設樞軸的關鍵字應該在第k的位置(1≤k≤n),那么: 用數學歸納法可證明,其數量級為0(nlogn).空間復雜度
其實這個空間復雜度不太好計算,因為有的人使用的是非就地排序,那樣就不好計算了(因為有的人用到了輔助數組,所以這就要計算到你的元素個數了);我就分析下就地快速排序的空間復雜度吧; 首先就地快速排序使用的空間是O(1)的,也就是個常數級;而真正消耗空間的就是遞歸調用了,因為每次遞歸就要保持一些數據; ? 穩定性: 由于關鍵字的比較和交換是跳躍進行的,因此,快速排序是不穩定的排序方法。轉載于:https://www.cnblogs.com/Allen-win/p/7307861.html
總結
以上是生活随笔為你收集整理的排序算法7---快速排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。