將乙個一維陣列從小到大排序。希爾排序是插入排序的優化方式,因為普通的插入排序會存在乙個問題,那就是當比較小的數字排在後面時,需要後移很多次才能完成。
由此,希爾排序的思路是:引入乙個步長的因素gep。之前的冒泡也好選擇也好插入也好,都是之間跟之前或之後的一個數字進行比較,然後再++或–。而希爾排序簡單來說就是跟步長之前的數字比較。
它有兩種形式,第一種是交換式。它的思路是:首先分多次進行排序,第一次的步長為陣列長度÷2,第二次步長為陣列長度÷2÷2。。。最後一次步長為1,也就是說步長第一次等於陣列長度除二,之後每次除二,保證它一直大於0(最後一次等於1,除二等於0,此時就退出)。在每一次迴圈內,為了保證每乙個數字都進行流水似的交換(也就是數字必須被和之前的和之後的都比較一次,這才能確保正確,)(而不是只交換一次,如果那樣就沒辦法正確排序,也就是較大的數換不到最後)讓i=步長,i小於陣列長度,每次加一。在迴圈中,讓j=i-gep,也就是每次從0開始,依次與加步長的值比較(這是為了跟後面的值比較),如果比它大,兩兩交換。j每次減gep(這是為了跟前面的值比較)。這種方法一般效率比較低。
第二種是插入式。他的思路是:同樣先用乙個迴圈劃分步長。每個迴圈內設定i=gep,i小於陣列長度,每次加一,這是為了遍歷到陣列中的每個數。在這個迴圈內,採用插入排序的思想,先保留下數字和索引,也就是i和arr[i],依次與步長個長度的之前的數比較,如果比較小,不要之間交換,而且將步長個長度的之前那個較大的數挪到當前索引位置下,然後索引每次減步長(也就是再和步長個長度之前的數作比較,還小就再挪),直到索引為0,這樣就與該數字之前的每個數字都做了比較(間隔步長),迴圈結束後,此時的索引對應的位置就是該數字arr[i]應該插入的位置,直接賦值即可。
這種方式效率非常高。
/**
* 交換式
* @param arr
*/private
static
void
shellsort
(int
arr)}}
}}/** * 插入式
* @param arr
*/private
static
void
shellsort2
(int
arr)
arr[j]
=temp;}}
}
希爾排序學習筆記
希爾排序時對插入排序的優化,當較小元素在靠後位置時,將會發生大量的移位,效率比較低下,而希爾排序通過分組使得後面的元素移到前面只需要很少的移位就可以完成,隨著分組的的容量逐漸減少,等到分組容量為1的時候排序基本完成了,再使用插入排序就只涉及很少的移位了 思路 一開始另分組容量為length 2,每次...
筆記 希爾排序
插入排序 將待排序元素分為已排序子集和未排序子集,一次從未排序子集中的乙個元素插入已排序子集中,使已排序自己仍然有序 重複執行以上過程,指導所有元素都有序為止。希爾排序又稱為縮小增量排序,它也是一種屬插入排序類的方法,但在事件效率上較前述集中排序方法都有較大的改進。從對直接插入排序的分析得知,其演算...
演算法筆記 希爾排序
希爾排序是直接插入排序 的改進版,對於待排序序列的不同情況效率相近。1.演算法思想 先選取乙個小於n的增量d1,把序列中所有元素分成n d1個組,所有距離為d1的倍數的元素在同一組中,在各組內執行直接插入排序。然後選取乙個更小的增量d2,重複上述分組和排序過程 繼續減小增量,直至增量為1,即所有元素...