序章
英語名:Straight Insertion Sort
も最も単純な並べ替え方法であり、その基本的な操作は、並べ替えられたリストにレコードを挿入し、レコード数が 1 増加した新しい並べ替えられたリストを取得することです。
ステップ
以下では、例として配列 2,5,8,3,6,9,1,4,7 を使用して、
小さいものから大きいものへと並べ替えます。
1. まず最初の数値を確認し、配列を順序付き部分と順序なし部分に分割します。
- まず最初の数字 2 を見てください。数字には順序が必要なので、2 を順番に分割し、残りは無秩序になります。
2. 順序付けられていない部分の順序付けされた部分への最初の挿入
- 未順序部分の最初の部分を取り出し、順序付き部分の前後を比較し、適切な位置に挿入します
3. 順序付けされていないすべてのパーツが順序どおりに挿入されるまで、ステップ 2 を繰り返します。
-
8も入れられる比較です
-
3 では複数の比較が必要ですが、1 つの比較と 1 つの挿入ではなく、複数の比較、直接挿入であることに注意してください (バブリングとは異なります)
次の手順も非常に簡単ですが、現在は省略されています。
コード
- 上記のプロセスから、このアルゴリズムはすべての数値を 1 回走査して個別に挿入することがわかりますが、最初の数値は順序どおりである必要があり、ソートする必要がないため、n 個の数値は n-1 回の走査が必要になります。
- つまり、i は 1 から直接開始します
- 各挿入の比較は前の数値から開始されるため、2 番目のループのパラメーター j を i-1 に直接設定できます。
- 挿入ごとに、まず挿入する番号を取り出します。
- 次に比較し、取り出した数値より大きい場合は、数値を戻します (j-1)。
- 次に比較します
- このとき、再度比較すると、3 未満の数値があるため、ループから抜け出し、配列に 3 を挿入でき、添字は j+1 になります。
- ループから抜け出すもう 1 つの方法は、先頭に進んでも、フェッチした数値より小さい数値がない場合に、直接ループから抜け出すことです。例として 1 を取り上げます。
- 次のステップは、ルール 2、j-1、この時点では j=-1 に従って後方に移動し、ループから抜け出します。1 は添字 j+1 の位置に配置されます。これは最初のステップであり、前のステップと一致します。
-
要約すると、j>=0 および temp<a[j]、そして最後に a[j+1]=temp を制限する必要があります。
-
最適化: 挿入する数値がすでに前の数値より大きい場合、取り出して再度挿入する必要はありません
#include<bits/stdc++.h>
using namespace std;
void InsertSort(int a[],int l)
{
int temp;
int j;
for(int i=1;i<l;i++)
{
if(a[i]<a[i-1])
{
temp=a[i];
for(j=i-1;j>=0&&temp<a[j];j--)
{
a[j+1]=a[j];
}
a[j+1]=temp;
}
for(int k=0;k<l;k++)
cout<<a[k]<<" ";
cout<<endl;
}
}
int main()
{
int a[10]={
2,5,8,3,6,9,1,4,7};
int b[10]={
1,2,3,4,5,6,7,8,9};
int len=9;
InsertSort(a,len);
return 0;
}
特性
1. 時間計算量
最良のケースは、すべてが順調であり、現時点で必要な走査は 1 つだけであり、最適な時間計算量はO ( n ) O(n)です。O ( n )
最悪の場合、すべてが逆になり、内側の層は毎回ソートされた部分を横断します。最悪の時間計算量はO ( n 2 ) O(n^2)O ( n2 )
要約すると、直接挿入ソートの平均時間計算量はO ( n 2 ) O(n^2)です。O ( n2 )
2. 空間の複雑さ
補助スペースは一定です
スペースの平均複雑さは次のとおりです: O ( 1 ) O(1)○ (1)
3. アルゴリズムの安定性
同じ要素の順序が変更されるかどうか
それより大きい数値の前に挿入されるため、直接挿入ソートが安定します
小さなテスト
-
上記のコードでは、出力された配列は次のようになります
-
順序付けられた配列が後方、つまり後方から前方に走査されるようにコードを変更できますか?
新しいアルゴリズム、古いルーチン、次回は新しいトリックをプレイしてみませんか? (≖ᴗ≖)✧