首先,國際慣例:
一、什麼是排序演算法?
所謂排序,就是使一串記錄,按照其中的某個或某些關鍵字的大小,遞增或遞減的排列起來的操作。排序演算法,就是如何使得記錄按照要求排列的方法。排序演算法在很多領域得到相當地重視,尤其是在大量資料的處理方面。乙個優秀的演算法可以節省大量的資源。在各個領域中考慮到資料的各種限制和規範,要得到乙個符合實際的優秀演算法,得經過大量的推理和分析。
二、排序演算法都包括什麼內容?
1、分類:(1)穩定的:
氣泡排序(bubble sort) — o(n^2)
雞尾酒排序(cocktail sort,雙向的氣泡排序) — o(n^2)
插入排序(insertion sort)— o(n^2)
桶排序(bucket sort)— o(n); 需要 o(k) 額外空間
計數排序(counting sort) — o(n+k); 需要 o(n+k) 額外空間
合併排序(merge sort)— o(nlog n); 需要 o(n) 額外空間
原地合併排序— o(n^2)
二叉排序樹排序 (binary tree sort) — o(nlog n)期望時間; o(n^2)最壞時間; 需要 o(n) 額外空間
鴿巢排序(pigeonhole sort) — o(n+k); 需要 o(k) 額外空間
基數排序(radix sort)— o(n·k); 需要 o(n) 額外空間
gnome 排序— o(n^2)
圖書館排序— o(nlog n) with high probability,需要 (1+ε)n額外空間
(2)不穩定的:
選擇排序(selection sort)— o(n^2)
希爾排序(shell sort)— o(nlog n) 如果使用最佳的現在版本
組合排序— o(nlog n)
堆排序(heapsort)— o(nlog n)
平滑排序— o(nlog n)
快速排序(quicksort)— o(nlog n) 期望時間,o(n^2) 最壞情況; 對於大的、亂數列表一般相信是最快的已知排序
introsort— o(nlog n)
patience sorting— o(nlog n+ k) 最壞情況時間,需要 額外的 o(n+ k) 空間,也需要找到最長的遞增子串行(longest increasing subsequence)
(3)不實用的:
bogo排序— o(n× n!) 期望時間,無窮的最壞情況。
stupid sort— o(n^3); 遞迴版本需要 o(n^2) 額外儲存器
珠排序(bead sort) — o(n) or o(√n),但需要特別的硬體
pancake sorting— o(n),但需要特別的硬體
stooge sort——o(n^2.7)很漂亮但是很耗時
2、常見的排序演算法:
插入排序
插入排序是這樣實現的:
1、首先新建乙個空列表,用於儲存已排序的有序數列(我們稱之為"有序列表")。
2、從原數列中取出乙個數,將其插入"有序列表"中,使其仍舊保持有序狀態。
3、重複2號步驟,直至原數列為空。
插入排序的平均時間複雜度為平方級的,效率不高,但是容易實現。它借助了"逐步擴大成果"的思想,使有序列表的長度逐漸增加,直至其長度等於原列表的長度。
插入排序的基本思想是在遍歷陣列的過程中,假設在序號 i 之前的元素即 [0..i-1] 都已經排好序,本趟需要找到 i 對應的元素 x 的正確位置 k ,並且在尋找這個位置 k 的過程中逐個將比較過的元素往後移一位,為元素 x 「騰位置」,最後將 k 對應的元素值賦為 x ,一般情況下,插入排序的時間複雜度和空間複雜度分別為 o(n2 ) 和 o(1)。[1]
氣泡排序
氣泡排序是這樣實現的:
1、從列表的第乙個數字到倒數第二個數字,逐個檢查:若某一位上的數字大於他的下一位,則將它與它的下一位交換。
2、重複1號步驟,直至再也不能交換。
氣泡排序的平均時間複雜度與插入排序相同,也是平方級的,但氣泡排序是原地排序的,也就是說它不需要額外的儲存空間。
選擇排序
選擇排序是這樣實現的:
1、設陣列內存放了n個待排數字,陣列下標從1開始,到n結束。
2、初始化i=1
3、從陣列的第i個元素開始到第n個元素,尋找最小的元素。
4、將上一步找到的最小元素和第i位元素交換。
5、i++,直到i=n-1演算法結束,否則回到第3步
選擇排序的平均時間複雜度也是o(n^2)的。
舉例:564
比如說這個,我想讓它從小到大排序,怎麼做呢?
第一步:從第一位開始找最小的元素,564中4最小,與第一位交換。結果為465
第二步:從第二位開始找最小的元素,465中5最小,與第二位交換。結果為456
第三步:i=2,n=3,此時i=n-1,演算法結束
完成快速排序
現在開始,我們要接觸高效排序演算法了。實踐證明,快速排序是所有排序演算法中最高效的一種。它採用了分治的思想:先保證列表的前半部分都小於後半部分,然後分別對前半部分和後半部分排序,這樣整個列表就有序了。這是一種先進的思想,也是它高效的原因。因為在排序演算法中,演算法的高效與否與列表中數字間的比較次數有直接的關係,而"保證列表的前半部分都小於後半部分"就使得前半部分的任何乙個數從此以後都不再跟後半部分的數進行比較了,大大減少了數字間不必要的比較。但查詢資料得另當別論了。
時間複雜度
平均時間複雜度
插入排序 o(n^2)
氣泡排序 o(n^2)
選擇排序 o(n^2)
快速排序 o(n log n)
堆排序 o(n log n)
歸併排序 o(n log n)
基數排序 o(n)
希爾排序 o(n^1.25) 三、
排序演算法小結
1 快速排序 quicksort 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來說,它是歸併排序的就地版本。快速排序可以由下面四步組成。1 如果不多於1個資料,直接返回。2 一般選擇序列最左邊的值作為支點資料。3 將序列分成2部分,一部分都大於支點資料,另外一部分都小於支點資料。4...
排序演算法小結
1 歸併排序 3.區別與聯絡 遞迴是從未知推到已知,相當於把未知的東西壓入棧,等到可以算出結果了,就一步一步出棧。迭代是從已知到未知,從已知的東西一步一步推至目標。遞迴與迭代就好像一對逆元。遞迴的 更加清晰,但開銷更大,也更容易出錯,除錯較困難 而迭代的 編寫更困難,但速度和開銷較小。4.空間占用 ...
排序演算法小結
演算法過程 假設乙個無序的序列,該演算法將其分成兩部分,前一部分已經完成排序 有序,一開始時只有乙個元素 後一部分任然無序,將後面序列選擇第乙個插入到前面的有序序列,如此直到所有完全有序。複雜度 最簡單的即為,整個序列原來即有序,按照一種最 省事 的方式,我們僅需比較n 1次即可。最複雜的情況,應該...