一、概念
快速排序由c.a.r.hoare在2023年提出,是氣泡排序的一種改進。其基本思想為:通過一趟排序將待排序資料分割成獨立的兩部分,其中一部分的所有值都比另一部分的所有值都小,然後再對分割的兩部分分別進行快速排序,整個過程可以遞迴進行,最終所有資料變為有序序列。
二、演算法要點
假設待排序陣列為a[0], a[1],…a[n-1],快速排序步驟以下:
1、初始化兩個變數i、j,剛開始i = 1,j=n-1。
2、將第乙個元素a[0]作為基準數。
3、從i開始向後搜尋,找到第乙個大於基準數的元素a[i]。
4、從j開始向前搜尋,找到第乙個小於等於基準數的元素a[j]。
5、將a[i]與a[j]互換。
6、重複3到5步驟,直到i = j + 1,此時,j指向的元素是最後乙個(從左邊算起)小於等於中軸的元素,然後將a[0]與a[j]對換。
7、序列被基準數分割成兩個分割槽,前面分割槽全部小於等於基準數,後面分割槽全部大於基準數。
8、遞迴對分割槽子串行進行快速排序,最終完成整個排序工作。
每趟快速排序的核心工作是:
選乙個元素作為基準數,然後將所有比它小的數都放到它前面,大於它的數都放在它後面。
三、演算法實現
實現一:
1using
system;
2using
system.collections.generic;34
namespace
quicksort513
private
static
void quicksort(listdatalist, int left, int
right)
1431
while(i <= j && datalist[j] >pivot)
3236
if(i 37 42}
43//
當迴圈結束時,j指向的元素是最後乙個(從左邊算起)小於等於中軸的元素
44//
將中軸元素和j所指的元素互換
45 tmp =datalist[left];
46 datalist[left] =datalist[j];
47 datalist[j] =tmp;
48console.writeline();
49foreach (var item in
datalist)50
");52}
53console.writeline();
54 quicksort(datalist, left, j - 1
);55 quicksort(datalist, j + 1
, right);56}
57}58private
static
void quicksortunittest(int
loopnum)
5966 console.write("
original data:");
67foreach(var item in
datalist)68
");70}
7172 quicksort(datalist, 0, datalist.count - 1
);73 console.write("
quick sorted data:");
7475
foreach (var item in
datalist)76
");78}
79console.writeline();80}
81}82 }
實現二:
基本思想:「挖坑填坑」
使用兩個變數i和j分別指向最左邊和最右邊的元素,我們將首元素作為中軸,並複製到變數pivot中,這時我們可以將首元素i所在的位置看成乙個坑,我們從j的位置從右向左掃瞄,找乙個小於等於中軸
的元素a[j],來填補a[i]這個坑,填補完成後,拿去填坑的元素所在的位置j又可以看做乙個坑,這時我們在以i的位置從前往後找乙個大於中軸的元素來填補a[j]這個新的坑,如此往復,直到
i和j相遇(i == j,此時i和j指向同乙個坑)。
最後我們將中軸元素放到這個坑中。然後,我們按照相同的方法分別對左右兩個陣列執行相同的操作。
privatestatic
void quicksort2(listdatalist, int left, int
right)
//填a[i]這個坑,填完後a[j]是個坑
//注意不能是a[i++] = a[j],當因i==j時跳出上面的迴圈時
//坑為i和j共同指向的位置,執行a[i++] = a[j],會導致i比j大1,
//但此時i並不能表示坑的位置
datalist[i] =datalist[j];
while(i < j && datalist[i] <=pivot)
datalist[j] =datalist[i];
}//迴圈結束後i和j相等,都指向坑的位置,將中軸填入到這個位置
datalist[i] =pivot;
quicksort2(datalist, left, i - 1
); quicksort2(datalist, i + 1
, right);
}}
排序 快速排序
快速排序時實踐中最快的一直排序,平均時間是0 nlogn 最壞的情況是o n2 但是很容易將這種情況避免 空間複雜度 o n lgn 不穩定。快速排序時基於分治模式處理的,對乙個典型子陣列a p.r 排序的分治過程為三個步驟 1.分解 a p.r 被劃分為倆個 可能空 的子陣列a p q 1 和a ...
排序 快速排序
定義 在快速排序演算法中,使用了分治策略,將要排序的序列分成兩個子串行,然後遞迴地對子序列進行排序,直到整個序列排序完畢。步驟 1.在序列中選擇乙個關鍵元素作為軸 2.對序列進行重新排序,將比軸小的元素移到軸的前邊,比軸大的元素移動到軸的後面。在進行劃分之後,軸便在它最終的位置上 3.遞迴地對兩個子...
排序 快速排序
時間複雜度 快速排序每次將待排序陣列分為兩個部分 1 在理想狀況下,每一次都將待排序陣列劃分成等長兩個部分,則需要logn次劃分。2 在最壞情況下,即陣列已經有序或大致有序的情況下,每次劃分只能減少乙個元素,快速排序將不幸退化為氣泡排序,最壞情況為o n 2 快速排序的平均時間複雜度為o nlogn...