序章
まず、直接挿入ソート
と二分探索について理解する必要があります。
英語名: バイナリ挿入ソートは、
直接挿入ソート アルゴリズムに基づいて改良されたアルゴリズムです。
ステップ
以下では、例として配列 2,5,8,3,6,9,1,4,7 を使用して、
小さいものから大きいものへと並べ替えます。
1. まず最初の数値を確認し、配列を順序付き部分と順序なし部分に分割します。
- まず最初の数字 2 を見てください。数字には順序が必要なので、2 を順番に分割し、残りは無秩序になります。
2.挿入位置を見つける
-
順序付けされていない部分の最初の部分を取り出し、順序付けされた部分の位置を見つけます
-
2,5,8は移動する必要がないので、3の挿入から直接開始します。
-
または、最初に挿入する番号を取り出します
-
次に、二分探索を使用して、挿入する必要がある位置を見つけます。
3.配列を移動し、最後に取り出した数値を挿入します
- 位置が見つかっているので、すべてを直接移動するため、1つずつ比較する必要はありません
- 入れる
次の手順は直接挿入と似ているため、説明されません。
コード
- 半挿入と直挿入の違いは挿入位置の求め方にあり
- 二分探索なのでlowとhighも導入され順序付け領域の境界として設定されます
- この数値が順序付けされた部分に存在しない場合、二分法の推論に従って、最終的な最低値と最高値は次のようになります。
- このような数がある場合、結果はどうなりますか?
- コードでは、Low と High が同じ場合、変化が小さいことに注意してください。
- それらはすべて低い位置から動き始め、最終的に低い位置に配置されることがわかります。
#include<bits/stdc++.h>
using namespace std;
void BInsertSort(int a[],int l)
{
int temp;
int low,high;
int m;
for(int i=1;i<l;i++)
{
if(a[i]<a[i-1])
{
low=0;
high=i-1;
while(low<=high)
{
m=low+(high-low)/2;
if(a[m]>a[i])
high=m-1;
else
low=m+1;
}
temp=a[i];
for(int j=i;j>low;j--)
a[j]=a[j-1];
a[low]=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;
BInsertSort(a,len);
return 0;
}
特性
1. 時間計算量
半探索では比較回数が減るだけですが、要素の移動回数は変わらないため、時間計算量はO ( n 2 ) O(n^2)となります。O ( n2 )
2. 空間の複雑さ
平均空間複雑度も次のようになります: O ( 1 ) O(1)○ (1)
3. アルゴリズムの安定性
同じ要素の順序が変更されるかどうかは上記の説明で述べましたが、配列 2 4 5 8 3 6 4 1 4 の
出力が毎回 Low になる、つまり挿入位置の値を例に見てみましょう。
- 後ろの同じ番号は同じ番号の後にのみ挿入されることがわかり、依然として安定した並べ替えアルゴリズムです。
小さなテスト
ちょっと内容がアレなのでやめておきます 変えるなら昔のルールそのままです 直挿しと同じです٩( 'ω' )و カニ
!