插入排序
從數(shù)組的第二個元素往下循環(huán),每一個數(shù)字都要和他上面的所有數(shù)字進行比較谱净,如果遇到比他大的數(shù)字仅政,那么比他大的數(shù)字就要下沉一個,比他小的數(shù)字不變静汤,大數(shù)字下沉后就會留出來一個空間琅催,那么當前數(shù)字就會插入到那個空間
Sub 插入排序()
Dim arr, temp, x, y, imax, k, k1, k2
arr = Range("a1:a10")
For x = 2 To UBound(arr)
temp = arr(x, 1)
For y = x - 1 To 1 Step -1
If arr(y, 1) <= temp Then Exit For '如果上面的數(shù)都沒有它大,沒必要再找虫给,跳出for循環(huán)藤抡,直接到下一步
arr(y + 1, 1) = arr(y, 1)
k1 = k1 + 1
Next y
arr(y + 1, 1) = temp '接上一步跳出for循環(huán)的語句
k2 = k2 + 1
Next x
Range("b2").Resize(UBound(arr)) = arr
MsgBox k1
End Sub
希爾排序
是插入排序法的改進版,大大提高了插入排序法的效率抹估。
原理:插入排序是挨著的缠黍,希爾排序是間隔的比較。插入排序下降一個位置药蜻,希爾排序下降一個間隔瓷式。需要設(shè)置很多間隔替饿。
Sub 希爾排序()
Dim arr
Dim 總大小, 間隔, x, y, temp, t
t = Timer
arr = Range("a1:a30")
總大小 = UBound(arr) - LBound(arr) + 1
間隔 = 1? ?'間隔初始值為1
If 總大小 > 13 Then???? '這里記住13,大于13計算間隔數(shù)贸典,小于的話就用插入排序法视卢,也就是間隔為1
Do While 間隔 < 總大小
間隔 = 間隔?* 3 + 1? '經(jīng)驗證這是最有效的間隔設(shè)置方法
Loop
間隔 = 間隔 \ 9? '反斜杠是四舍五入取整數(shù)的意思,比如9\4就是2
End If
Do While 間隔? ?'使用多個間隔來計算廊驼,使用do while 循環(huán)
For x = LBound(arr) + 間隔 To UBound(arr) '從這里開始就是插入排序法了
temp = arr(x, 1)
For y = x - 間隔 To LBound(arr) Step -間隔
If arr(y, 1) <= temp Then Exit For
arr(y + 間隔, 1) = arr(y, 1)
k1 = k1 + 1
Next y
arr(y + 間隔, 1) = temp
Next x
間隔 = 間隔 \ 3
Loop
MsgBox k1 'k是計數(shù)器据过,可以看到多少次
Range("b2").Resize(UBound(arr)) = arr
End Sub
總結(jié):希爾排序是基于插入排序的以下兩點性質(zhì)而提出改進方法的:
插入排序在對幾乎已經(jīng)排好序的數(shù)據(jù)操作時,效率高妒挎,即可以達到線性排序的效率
但插入排序一般來說是低效的绳锅,因為插入排序每次只能將數(shù)據(jù)移動一位
算法思路:
先取一個正整數(shù) d1(d1 < n),把全部記錄分成 d1 個組酝掩,所有距離為 d1 的倍數(shù)的記錄看成一組榨呆,然后在各組內(nèi)進行插入排序
然后取 d2(d2 < d1)
重復(fù)上述分組和排序操作;直到取 di = 1(i >= 1) 位置庸队,即所有記錄成為一個組积蜻,最后對這個組進行插入排序。一般選 d1 約為 n/2彻消,d2 為 d1 /2竿拆, d3 為 d2/2 ,…宾尚, di = 1丙笋。
上述信息摘自http://bubkoo.com/2014/01/15/sort-algorithm/shell-sort/
關(guān)于希爾排序的間隔一點補充,涉及到步長的選擇
內(nèi)容摘自http://blog.csdn.net/u010383982/article/details/42302623