插入排序
從數(shù)組的第二個(gè)元素往下循環(huán),每一個(gè)數(shù)字都要和他上面的所有數(shù)字進(jìn)行比較,如果遇到比他大的數(shù)字,那么比他大的數(shù)字就要下沉一個(gè),比他小的數(shù)字不變,大數(shù)字下沉后就會留出來一個(gè)空間,那么當(dāng)前數(shù)字就會插入到那個(gè)空間
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
希爾排序
是插入排序法的改進(jìn)版,大大提高了插入排序法的效率。
原理:插入排序是挨著的,希爾排序是間隔的比較。插入排序下降一個(gè)位置,希爾排序下降一個(gè)間隔。需要設(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計(jì)算間隔數(shù),小于的話就用插入排序法,也就是間隔為1
Do While 間隔 < 總大小
間隔 = 間隔?* 3 + 1? '經(jīng)驗(yàn)證這是最有效的間隔設(shè)置方法
Loop
間隔 = 間隔 \ 9? '反斜杠是四舍五入取整數(shù)的意思,比如9\4就是2
End If
Do While 間隔? ?'使用多個(gè)間隔來計(jì)算,使用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是計(jì)數(shù)器,可以看到多少次
Range("b2").Resize(UBound(arr)) = arr
End Sub
總結(jié):希爾排序是基于插入排序的以下兩點(diǎn)性質(zhì)而提出改進(jìn)方法的:
插入排序在對幾乎已經(jīng)排好序的數(shù)據(jù)操作時(shí),效率高,即可以達(dá)到線性排序的效率
但插入排序一般來說是低效的,因?yàn)椴迦肱判蛎看沃荒軐?shù)據(jù)移動一位
算法思路:
先取一個(gè)正整數(shù) d1(d1 < n),把全部記錄分成 d1 個(gè)組,所有距離為 d1 的倍數(shù)的記錄看成一組,然后在各組內(nèi)進(jìn)行插入排序
然后取 d2(d2 < d1)
重復(fù)上述分組和排序操作;直到取 di = 1(i >= 1) 位置,即所有記錄成為一個(gè)組,最后對這個(gè)組進(jìn)行插入排序。一般選 d1 約為 n/2,d2 為 d1 /2, d3 為 d2/2 ,…, di = 1。
上述信息摘自http://bubkoo.com/2014/01/15/sort-algorithm/shell-sort/
關(guān)于希爾排序的間隔一點(diǎn)補(bǔ)充,涉及到步長的選擇
內(nèi)容摘自http://blog.csdn.net/u010383982/article/details/42302623