目次
挿入ソートに基づく最適化 - ヒルソート (縮小増分ソート)
================================================= =======================
================================================= =======================
序文
これは新しいアルゴリズム コラムです。ご存知のとおり、アルゴリズムは比較的難しく、非常に頭を使うものです。前号では、誰もがそれに慣れるのに役立つ簡単な並べ替えアルゴリズムをいくつか紹介します。今日の第 1 号では、挿入ソートと挿入ソート用の最適化されたヒルソートが提供されます。
1. ソートの概念とその応用
成績、企業ランキング、大学ランキング、食品ソフトの店舗ランキングなど、並べ替えは日常のいたるところで見られます。それらはすべて並べ替えですが、並べ替えとは何でしょうか。並べ替えを実装するにはどうすればよいですか? よく聞いてください。
1.1 ソートの概念
並べ替え: いわゆる並べ替えは、レコードの文字列を、その中の 1 つまたはいくつかのキーワードのサイズに従って昇順または降順に並べる操作です。
安定性: ソートされるレコード シーケンスに同じキーワードを持つ複数のレコードがあると仮定します。ソートされた場合、これらのレコードの相対的な順序は変更されません。つまり、元のシーケンス r[i]=r[j] になります。 r[i] が r[j] より前にあり、ソートされたシーケンス内で r[i] がまだ r[j] より前にある場合、このソート アルゴリズムは安定と呼ばれ、それ以外の場合は不安定と呼ばれます。
内部ソート: すべてのデータ要素がメモリ内に配置されるソート。
外部ソート: 同時にメモリに配置できないデータ要素が多すぎるため、ソート プロセスの要件に従って、データを内部メモリと外部メモリ間で移動できません。
1.2 ソートの適用
1.3 一般的な並べ替えアルゴリズム
2. 挿入ソートの実装
基本的な考え方: すべてのレコードが挿入され、新しい順序付けされたシーケンスが取得されるまで、キー値のサイズに従って、並べ替えるレコードを既に並べ替えられた順序付けされたシーケンスに 1 つずつ挿入します。
人生における挿入ソート
カード ゲームが好きな友達は、ポーカーや麻雀に精通しているはずです。カードを整理するときは、挿入ソートを使用します
i(i>=1)要素を挿入する際には、前のarray[0]、array[1]、...、array[i-1]がソートされていますので、このときarray[i]のソートコードを使用します。 ]とarray[i-1]、array[i-2]、…のソートコード順を比較し、挿入位置が見つかったらarray[i]を挿入し、元の要素の順序を戻す位置が後ろに移動します。
簡単に言うと、配列内の最後の有効なデータが挿入したいデータであり、以前に並べ替えられたデータと順番に比較され、最終的に適切な位置に配置されます。
直接挿入ソートの特性の概要:
1. 要素セットの順序が近いほど、直接挿入ソート アルゴリズムの時間効率が高くなります。
2. 時間計算量: O(N^2)
3. 空間計算量: O(1 )、これは安定した並べ替えアルゴリズムです。
4. 安定性:安定しています。
コードを実装する
void InsertSort(int* a, int n)
{
//[0,end]有序,把end+1位置的插入到前序序列
//控制[0,end+1]有序
for (int i = 0; i < n - 1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + 1] = a[end];
}
else
{
break;
}
end--;
}
a[end + 1] = tmp;
}
}
挿入ソートに基づく最適化 - ヒルソート (縮小増分ソート)
ヒルソート法は、縮小増分法とも呼ばれます。ヒル ソート法の基本的な考え方は、まず整数を選択し、ファイル内のソート対象のすべてのレコードをグループに分割し、距離のあるすべてのレコードを同じグループに入れて、各グループ内のレコードをソートします。次に、上記のグループ化と並べ替えの作業を繰り返します。=1 に達すると、すべてのレコードが同じグループにソートされます。
ヒルソートのステップ:
1. グループ化する配列の長さより小さい整数 (ギャップとして示されます) を選択し、挿入ソートを使用して各グループを事前にソートします。
2. プログラムが進むにつれてギャップが徐々に減少し、ギャップが 1 になったときは挿入ソートです。
コードを実装する
while (gap > 1)
{
gap = gap / 2;
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end = end - gap;
}
else
{
break;
}
a[end + gap] = tmp;
}
}
}
ヒル ソートの特徴の概要:
1. ヒル ソートは、直接挿入ソートの最適化です。
2. ギャップ > 1 の場合、配列を順序に近づけるために事前にソートされます。ギャップ == 1 の場合、配列はすでにほぼ順序付けられているため、高速になります。このようにして、全体的な最適化の結果を達成できます。実装した後、パフォーマンス テストを比較できます。
3. ギャップを評価する方法が多数あるため、ヒル ソートの時間計算量は計算が困難であり、そのため、多くのツリーで与えられるヒル ソートの時間計算量は固定されていません。
「データ構造(C言語版)」 --- ヤン・ウェイミン
「データ構造 - オブジェクト指向手法と C++ を使用した記述」 --- ying Renkun
私たちのギャップは Knuth によって提案された方法に従って計算されており、Knuth は多数の実験統計を行っているため、O (n^1.25) から O (1.6*n^1.25) に従って一時的に計算します。
ヒルソートの意味: 大きい番号はより速く後ろに移動し、小さい番号はより速く前に移動します。ギャップが大きいほどジャンプが速く、ギャップが小さいほど挿入ソートに近く、gap==1 の場合は挿入ソートになります。
本日の挿入ソートはここまで、次号ではセレクションソートをお届けしますので、お楽しみに!!!