挿入ソートを実現するC言語
1つ、直接挿入ソート
1.1基本的な考え方
直接挿入ソートは単純な挿入ソート方法です。基本的な考え方は
、すべてのレコードが挿入されるまで、キーコード値のサイズに従って1つずつソートされた順序付けられたシーケンスにソートされるレコードを挿入することです。新しい順序付けられたシーケンスを取得します。
実際には、ポーカーをプレイするときは、挿入ソートのアイデアを使用します
1.2コードの実装
次の図に示すように、配列[0、end]がすでに順序付けられた配列であると仮定して、最初に1行のみの並べ替えを挿入するコードを記述します。次に、並べ替えられる要素の添え字はend + 1、添え字です。 (end +1)要素はtmpに格納され、a [end]と比較されます。tmp<a [end]である限り、添え字がendである要素は後方に移動し、endは左に移動します。後方に移動すると、スペースが確保されます。 Insert tmpの場合、tmpが条件を満たさなくなるまで、ループを停止し、tmpを適切な位置end +1に挿入します。
このようにして、挿入ソートのコードを書くことができます
int end=i; //有序数组最后一个元素的下标
int tmp = a[end + 1]; //待插入元素存入临时变量tmp
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + 1] = a[end]; //1.end下标元素向后挪方便tmp的插入
--end; //2.end左移进行下一轮的比较
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
}
a[end + 1] = tmp; //将tmp插入到数组当中
完全なコードは、挿入ソートを実現するために末尾を移動するだけで済みます。デフォルトではend = 0です。つまり、最初の要素が順序付けられ、最後が後方に移動し、各要素が前の順序の要素と比較されます。これで、endの開始条件は0から開始し、end = n-2になります。これは、end = n-2の場合、ソートされる要素のインデックスがn-1、つまりインデックスであるためです。配列の最後の要素の、終了の間隔は[0、n-2]です。通常、この間隔を左閉と右開、つまり[0、n-1)と記述します。
// 插入排序
void InsertSort(int* a, int n)
{
//默认第一个数已经是有序
for (int i = 0; i < n-1; ++i)
{
int end=i; //有序数组最后一个元素的下标
int tmp = a[end + 1]; //待插入元素存入临时变量tmp
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + 1] = a[end]; //1.end下标元素向后挪方便tmp的插入
--end; //2.end左移进行下一轮的比较
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
}
a[end + 1] = tmp; //将tmp插入到数组当中
}
}
試験結果
//打印数组
void PrintArr(int* a, int n)
{
for (int i = 0; i < n; ++i)
{
printf("%d ", a[i]);
}
printf("\n");
}
void TestInsertSort()
{
int a[] = {
2,4,7,2,6,4,5,7,8,32,33,11 };
int n = sizeof(a) / sizeof(a[0]);
PrintArr(a, n);
InsertSort(a, n);
PrintArr(a, n);
}
int main()
{
TestInsertSort();
system("pause");
return 0;
}
1.3機能の概要
直接挿入ソートの特徴の要約:
- 要素のセットが近いほど、直接挿入ソートアルゴリズムの時間効率が高くなります。
- 時間計算量:O(N ^ 2)
- スペースの複雑さ:O(1)、安定ソートアルゴリズムです
- 安定性:安定
第二に、ヒルソート
1.1基本的な考え方
ヒルソート法は、減増分法とも呼ばれます。ヒルソート方法の基本的な考え方は次のとおりです:
最初に整数ギャップ(通常はgap = gap / 3 + 1)を選択し、ソートする配列をギャップグループに分割し、ギャップの距離を持つすべての要素を同じグループに配置します、および各グループ内の要素が並べ替えられます。次に、整数ギャップを再選択し、上記のグループ化と並べ替えの作業を繰り返します。場合時間= 1つのGAP、その後直接挿入ソートを実行し、確保するためにすべてのこと要素の順序付けします。
1.2コードの実装
同様に、配列の長さがn = 10、gap = gap / 3 + 1であると仮定し、最初に一連のソートコードを記述します。
- ギャップ= 4の場合、配列は(9,7,3)、(1,4,5)、(2,8)、(5,6)の4つのグループに分割され、これら4つのグループで挿入ソートを実行します。結果は(3,7,9)、(1,4,5)、(2,8)、(5,6)です。
ギャップ= 4の並べ替えのプロセスをマスターした後、最初にこの並べ替えを記述しましょう。
まずが可変端アレイ9の最初の要素から= 0開始を定義する、次の要素はエンド+ギャップ要素は添字TMP挿入される下部が7で、我々は、としてマーク法律、端要素4行く、4を見つけることができます5の場合、endの区間添え字は[0,5]であると判断できます。通常、右側の区間を開いた区間に変換します。たまたま[0、n-gap)であることがわかります。信じられない場合は、ステップ2、3の分析を引き続き確認して、一連の並べ替えコードを記述できます。
gap = gap/3+1;
for (int i = 0; i < n - gap; ++i) //i从0开始到n-gap结束
{
int end = i;
int tmp = a[end + gap]; //每次增加gap的步长作为插入元素
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + gap] = a[end]; //1.end下标元素向后挪方便tmp的插入,这里end挪动的步长是gap而不是1了
end -= gap; //2.end左移进行下一轮的比较,同理左移gap步长
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
a[end + gap] = tmp; //将tmp插入到数组当中
}
}
- ギャップ= 2、配列は2つのグループ(3,2,7,8,9)、(1,5,4,6,5)に分割され、これら2つのグループに対してそれぞれ挿入ソートを実行すると、結果は(2 、3、7、8、9)、(1、4、5、5、6)。このステップでは、終了の間隔が[0、8)、8 = n-gap = 10-2であることがわかります。
- ギャップ= 1、配列は2つのグループ(3,2,7,8,9)、(1,5,4,6,5)に分割され、これら2つのグループに対してそれぞれ挿入ソートを実行すると、結果は(2 、3、7、8、9)、(1、4、5、5、6)。このステップでは、終了の間隔が[0、9)、9 = n-gap = 10-1であることがわかります。また、このステップは、挿入ソートの終了の終了条件がn-1 = 10であることも証明します。 -1 = 9
ヒルソートの手順を理解したら、ギャップのループコードを4から2、次に1に記述するだけです。この手順は非常に簡単です。最初にgap = nを定義し、毎回gap = gap / 3 +1をループします。 、最後の+1は、ギャップが1に等しくなることを保証することです。これは、配列が正しいことを保証することです。
// 希尔排序
void ShellSort(int* a, int n)
{
//1.gap>1时为预排序,让数列更接近有序
//2.gap=1为直接插入排序,保证有序
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1; //通常的
for (int i = 0; i < n - gap; ++i) //i从0开始到n-gap结束
{
int end = i;
int tmp = a[end + gap]; //每次增加gap的步长作为插入元素
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + gap] = a[end]; //1.end下标元素向后挪方便tmp的插入,这里end挪动的不长是gap而不是1了
end -= gap; //2.end左移进行下一轮的比较,同理左移gap步长
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
a[end + gap] = tmp; //将tmp插入到数组当中
}
}
}
}
試験結果
void TestShellSort()
{
int a[] = {
2,4,7,2,6,4,5,7,8,32,33,11 };
int n = sizeof(a) / sizeof(a[0]);
PrintArr(a, n);
ShellSort(a, n);
PrintArr(a, n);
}
int main()
{
//TestInsertSort();
TestShellSort();
system("pause");
return 0;
}
1.3機能の概要
ヒルソーティングの機能の概要:
- ヒルソートは、直接挿入ソートの最適化です。
- ギャップ> 1の場合、それらはすべて事前にソートされています。目的は、配列を順序に近づけることです。ギャップ== 1の場合、配列はすでに順序に近いため、非常に高速になります。このようにして、全体として、最適化された効果を達成することができます。それを認識した後、パフォーマンステストを比較できます。
- ヒルソートの時間計算量は計算が容易ではなく、推定する必要があり、平均時間計算量は次のように導き出されます。O(N 1.3—N 2)
- 安定性:不安定