ヒルソート
1959年に、Donald L. Shell (March 1, 1924 – November 2, 2015)
アメリカ人という名前Communications of the ACM 国际计算机学会月刊
の並べ替えアルゴリズムがリリースされ、ヒル並べ替えという名前のアルゴリズムが誕生しました。
注:ACM = Association for Computing Machinery
1947年に設立された、コンピュータ実践者のための世界的な専門組織であるInternational Computer Societyは、世界で最初の科学的および教育的コンピュータ社会です。
ヒルソートは直接挿入ソートの改良版です。直接挿入ソートは、ほとんどソート済みのシーケンスに対して非常に効率的であるため、O(n)
線形の複雑さを実現しますが、一度に1ビットしかデータを移動できません。Hillのクリエイティブソートでは、データをn
少しシフトすることができ、その後、n
常に直接挿入ソートと同じに削減されます1
。次の分析を参照してください。
ヒルソートは挿入ソートアルゴリズムです。
1.アルゴリズムの紹介
N
一連の数字があります:
- 最初により小さい
N
整数を取り、d1
位置がd1
整数の倍数である数値を1つのグループにまとめ、これらの数値を直接挿入して並べ替えます。 - 次に、より小さい
d1
整数を取り、d2
位置がd2
整数の倍数である数値を1つのグループにまとめ、数値を直接挿入して並べ替えます。 - 次に、より小さい
d2
整数を取り、d3
位置がd3
整数の倍数である数値を1つのグループにまとめ、数値を直接挿入して並べ替えます。 - ...
- integerが得られるまで
d=1
、直接挿入ソートを使用します。
これはグループ化挿入方法です。最後の反復は直接挿入ソートに相当し、他の反復はn
直接挿入ソートに距離を移動するたびに相当します。これらの整数は2つの数値間の距離です。
シーケンスの長さの半分を増分として受け取り、増分が1になるまで毎回半分にします。
簡単な例として、Hillは12個の要素のシーケンスを並べ替え[5 9 1 6 8 14 6 49 25 4 6 3]
ます。インクリメントd
値は次のとおりです6,3,1
::
x 表示不需要排序的数
取 d = 6 对 [5 x x x x x 6 x x x x x] 进行直接插入排序,没有变化。
取 d = 3 对 [5 x x 6 x x 6 x x 4 x x] 进行直接插入排序,排完序后:[4 x x 5 x x 6 x x 6 x x]。
取 d = 1 对 [4 9 1 5 8 14 6 49 25 6 6 3] 进行直接插入排序,因为 d=1 完全就是直接插入排序了。
シーケンスの順序付けが多いほど、直接挿入ソートの効率が高くなります。ヒルソートは、グループ化による直接挿入ソートを使用します。ステップサイズが1
大きいため、順序付けられていないシーケンスを最初は無秩序に少なく変更できます。交換の数も減り、1
直接挿入ソートの最後のステップが使用されるまで、シーケンスはすでに比較的順序付けられているので、時間の複雑さが少し良くなります。
最良の場合、つまりシーケンスが順序付けられている場合、logn
各直接挿入ソートの最適な時間の複雑さは次のとおりであるO(n)
ため、ヒルソートはサブインクリメンタル直接挿入ソートを実行する必要があります。したがって、ヒルソートに最適な時間複雑:O(nlogn)
。
最悪の場合、増分シーケンスが次のとおりであると想定して、各反復は最悪です。d8 d7 d6 ... d3 d2 1
次に、直接挿入されるソート要素の数は次のとおりです。n/d8 n/d7 n/d6 .... n/d3 n/d2 n
次に、時間の複雑さが直接挿入の最悪の複雑さとして計算されます。 :
假设增量序列为 ⌊N/2⌋ ,每次增量取值为比上一次的一半小的最大整数。
O( (n/d8)^2 + (n/d7)^2 + (n/d6)^2 + ... + (n/d2)^2 + n^2)
= O(1/d8^2 + 1/d7^2 + 1/d6^2 + ... + 1/d2^2 + 1) * O(n^2)
= O(等比为1/2的数列和) * O(n^2)
= O(等比求和公式) * O(n^2)
= O( (1-(1/2)^n)/(1-1/2) ) * O(n^2)
= O( (1-(1/2)^n)*2 ) * O(n^2)
= O( 2-2*(1/2)^n ) * O(n^2)
= O( < 2 ) * O(n^2)
したがって、ヒルソートの最悪の時間の複雑さはO(n^2)
です。
グループ化の増分シーケンスが異なると、時間の複雑さが異なりますが、どのシーケンスが最適であるかを証明することはできません。Hibbard
インクリメンタルシーケンス:1,3,7,···,2n−1
パケットの順序が広く証明することができ、時間の複雑さは、次のとおりですΘ(n^1.5)
。
ヒルのソートの時間の複雑さはこの範囲O(n^1.3)~O(n^2)
にあります。数学で厳密に証明することは不可能です。
グループ化の各ラウンドは直接挿入ソートを使用するため、ヒルソートは安定していませんが、グループ化はn
位置にまたがるため、2つの同一の番号が発生し、相手が見つからない場合、順序の変更は見つかりません。
2.アルゴリズムの実装
package main
import "fmt"
// 增量序列折半的希尔排序
func ShellSort(list []int) {
// 数组长度
n := len(list)
// 每次减半,直到步长为 1
for step := n / 2; step >= 1; step /= 2 {
// 开始插入排序,每一轮的步长为 step
for i := step; i < n; i += step {
for j := i - step; j >= 0; j -= step {
// 满足插入那么交换元素
if list[j+step] < list[j] {
list[j], list[j+step] = list[j+step], list[j]
continue
}
break
}
}
}
}
func main() {
list := []int{5}
ShellSort(list)
fmt.Println(list)
list1 := []int{5, 9}
ShellSort(list1)
fmt.Println(list1)
list2 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
ShellSort(list2)
fmt.Println(list2)
list3 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3, 2, 4, 23, 467, 85, 23, 567, 335, 677, 33, 56, 2, 5, 33, 6, 8, 3}
ShellSort(list3)
fmt.Println(list3)
}
出力:
[5]
[5 9]
[1 3 4 5 6 6 6 8 9 14 25 49]
[1 2 2 3 3 4 4 5 5 6 6 6 6 8 8 9 14 23 23 25 33 33 49 56 85 335 467 567 677]
以前に分析されたいくつかのソートアルゴリズムによると、ソートされる配列が小規模の場合、直接挿入ソートを使用することが一般的に推奨されます。ヒルソートは中規模の場合に使用できますが、大規模でも迅速なソート、マージソート、またはヒープが必要です。並べ替え。
シリーズ記事エントリー
私は、スター陳思い、私が個人的に書かれているようこそ(Golangが達成)のデータ構造とアルゴリズムの記事で始まる、より親しみやすいGitBookを読むために。
- データ構造とアルゴリズム(Golang実装)(1)Golang-Prefaceの簡単な紹介
- データ構造とアルゴリズム(Golang実装)(2)Golangパッケージ、変数、関数の簡単な紹介
- データ構造とアルゴリズム(Golang実装)(3)Golangフロー制御ステートメントの簡単な紹介
- データ構造とアルゴリズム(Golang実装)(4)Golang構造とメソッドの簡単な紹介
- データ構造とアルゴリズム(Golang実装)(5)Golangインターフェースの簡単な紹介
- データ構造とアルゴリズム(Golang実装)(6)Golang並行性、コルーチン、チャネルの簡単な紹介
- データ構造とアルゴリズム(Golang実装)(7)Golang標準ライブラリの簡単な紹介
- データ構造とアルゴリズム(Golang実装)(8.1)基本的な知識-序文
- データ構造とアルゴリズム(Golang実装)(8.2)基本的な知識-分割と征服と再帰
- データ構造とアルゴリズム(Golang実装)(9)基本的な知識アルゴリズムの複雑さとプログレッシブシンボル
- データ構造とアルゴリズム(Golang実装)(10)基本知識-アルゴリズムの複雑さの主な方法
- データ構造とアルゴリズム(Golang実装)(11)一般的なデータ構造-序文
- データ構造とアルゴリズム(Golang実装)(12)一般的なデータ構造にリンクされたリスト
- データ構造とアルゴリズム(Golang実装)(13)一般的なデータ構造-可変長配列
- データ構造とアルゴリズム(Golang実装)(14)一般的なデータ構造-スタックとキュー
- データ構造とアルゴリズム(Golang実装)(15)一般的なデータ構造-リスト
- データ構造とアルゴリズム(Golang実装)(16)一般的なデータ構造-辞書
- データ構造とアルゴリズム(Golang実装)(17)一般的なデータ構造ツリー
- データ構造とアルゴリズム(Golang実装)(18)ソートアルゴリズム-序文
- データ構造とアルゴリズム(Golang実装)(19)ソートアルゴリズム-バブルソート
- データ構造とアルゴリズム(Golang実装)(20)ソートアルゴリズム選択ソート
- データ構造とアルゴリズム(Golang実装)(21)ソートアルゴリズム挿入ソート
- データ構造とアルゴリズム(Golang実装)(22)ソートアルゴリズム-ヒルソート
- データ構造とアルゴリズム(Golang実装)(23)ソートアルゴリズム-マージソート
- データ構造とアルゴリズム(Golang実装)(24)ソートアルゴリズム-優先度キューとヒープソート
- データ構造とアルゴリズム(Golang実装)(25)ソートアルゴリズム-迅速なソート
- データ構造とアルゴリズム(Golang実装)(26)ルックアップアルゴリズム-ハッシュテーブル
- データ構造とアルゴリズム(Golang実装)(27)検索アルゴリズム-バイナリ検索ツリー
- データ構造とアルゴリズム(Golang実装)(28)検索アルゴリズム-AVLツリー
- データ構造とアルゴリズム(Golang実装)(29)検索アルゴリズム-2-3ツリーと左寄りの赤黒ツリー
- データ構造とアルゴリズム(Golangによって実装)(30)検索アルゴリズム-2-3-4ツリーと通常の赤黒ツリー