演算法系列「希爾排序」篇
常見的內部排序演算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸併排序、快速排序、堆排序、基數排序等。用一張圖概括:
關於時間複雜度:
1. 平方階 (O(n2)) 排序各類簡單排序:直接插入、直接選擇和冒泡排序。
2. 線性對數階 (O(nlog2n)) 排序快速排序、堆排序和歸併排序;
3. O(n1+§))排序,§ 是介於 0 和 1 之間的常數。希爾排序
4. 線性階 (O(n)) 排序基數排序,此外還有桶、箱排序。
關於穩定性:
穩定的排序演算法:冒泡排序、插入排序、歸併排序和基數排序。
不是穩定的排序演算法:選擇排序、快速排序、希爾排序、堆排序。
名詞解釋:
n:數據規模
k:「桶」的個數
In-place:佔用常數內存,不佔用額外內存
Out-place:佔用額外內存
穩定性:排序後 2 個相等鍵值的順序和排序之前它們的順序相同
希爾排序
希爾排序(Shell Sort)是插入排序的一種。是針對直接插入排序演算法的改進。該方法又稱縮小增量排序,因DL.Shell於1959年提出而得名。
希爾排序,也稱遞減增量排序演算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序演算法。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率;
但插入排序一般來說是低效的,因為插入排序每次只能將數據移動一位;
希爾排序的基本思想是:先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄「基本有序」時,再對全體記錄進行依次直接插入排序。
1. 選擇一個增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
2. 按增量序列個數 k,對序列進行 k 趟排序;
3. 每趟排序,根據對應的增量 ti,將待排序列分割成若干長度為 m 的子序列,分別對各子表進行直接插入排序。僅增量因子為 1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。
2. JavaScript 代碼實現functionshellSort(arr) {
var len =arr.length,
temp,
gap =1;
while(gap < len/3) { //動態定義間隔序列
gap =gap*3+1;
}
for (gap; gap >0; gap =Math.floor(gap/3)) {
for (var i = gap; i < len; i++) {
temp = arr[i];
for (var j = i-gap; j >=0&& arr[j] > temp; j-=gap) {
arr[j+gap] = arr[j];
}
arr[j+gap] = temp;
}
}
return arr;
}
3. Python 代碼實現
def shellSort(arr):
import math
gap=1
while(gap < len(arr)/3):
gap = gap*3+1
while gap > 0:
for i in range(gap,len(arr)):
temp = arr[i]
j = i-gap
while j >=0 and arr[j] > temp:
arr[j+gap]=arr[j]
j-=gap
arr[j+gap] = temp
gap = math.floor(gap/3)
return arr
}
4. Go 代碼實現
func shellSort(arr []int) int {
length := len(arr)
gap := 1
for gap < gap/3 {
gap = gap*3 + 1
}
for gap > 0 {
for i := gap; i < length; i++ {
temp := arr[i]
j := i - gap
for j >= 0 && arr[j] > temp {
arr[j+gap] = arr[j]
j -= gap
}
arr[j+gap] = temp
}
gap = gap / 3
}
return arr
}
5.Java代碼實現
public void shellSort(int[] list) {
int gap = list.length / 2;
while (1 <= gap) { // 把距離為 gap 的元素編為一個組,掃描所有組 for (int i = gap; i < list.length; i++) { int j = 0; int temp = list[i]; // 對距離為 gap 的元素組進行排序 for (j = i - gap; j >= 0 && temp < list[j]; j = j - gap) { list[j + gap] = list[j]; } list[j + gap] = temp; } System.out.format("gap = %d: ", gap); printAll(list); gap = gap / 2; // 減小增量 } }


※Oracle 12C 新特性之 恢復表
※WBS任務分解中前置任務閉環迴路檢測:有向圖的簡單應用(C)
※前台通用控制頁碼顯示的JS代碼
※js實用方法記錄-js動態載入css、js腳本文件
※JAVAWEB學習筆記21_多條件查詢、attr和prop的區別和分頁的實現
TAG:科技優家 |
※演算法——選擇排序
※「演算法」什麼是桶排序
※排序演算法總結
※排序演算法 冒泡排序
※演算法——狄克斯特拉演算法
※C語言編程基礎入門經典排序演算法——冒泡排序法
※十大經典排序演算法
※演算法餘暉
※前端排序演算法總結
※啥是佩奇排名演算法?
※什麼是插入排序演算法?
※區塊鏈系列:散列演算法
※推薦系統產品與演算法概述
※讓演算法解放演算法工程師——NAS 綜述
※演算法——分治和快速排序
※理解關聯規則演算法:演算法應用
※一本簡單的演算法書––––《演算法圖解》
※奇畫策演算法孝直
※「乾貨」解析亞馬遜A9演算法系列之類目節點
※漫畫:什麼是字典序演算法?