挿入ソート
挿入ソートは、単純な比較ベースのソートアルゴリズムです。このアルゴリズムでは、ソートされた部分配列とソートされていない部分配列の 2つの部分配列を保持します。ソートされていない部分配列から 1つの要素が、ソートされた部分配列の中で正しい位置を見つけ、そこに挿入されます。これは、ある人が手に持っているカードの山を並べ替えるのに似ています。これは、正しい位置に要素を挿入するように動作するので、挿入ソートと名付けられています。このアルゴリズムは、小さなデータセットには効率的ですが、大きなデータセットには適していません。
挿入ソートアルゴリズム
n 個の要素を含むソートされていない配列 A[]
があると仮定します。最初の要素 A[0]
は既にソートされており、ソートされた部分配列の中にあります。
-
並び替えられていない部分配列
A[1]
の最初の要素をキーとします。 -
次に、このキーをソートされた部分配列の要素と比較します。
-
キーが
A[0]
より大きければ、それをA[0]
の後に挿入します。 -
逆に小さい場合は、再度比較して
A[0]
の前の正しい位置に挿入します。(A[0]
の場合は 1つの位置しかない) -
次の要素
A[2]
をキーとします。ソートされた部分配列の要素と比較して、A[2]
よりも小さい要素の後に挿入します。小さい要素がない場合は、ソートされた部分配列の先頭に挿入します。 -
ソートされていない部分配列のすべての要素に対して上記の手順を繰り返します。
挿入ソートの例
配列 (5,3,4,2,1)
があるとします。挿入ソートアルゴリズムを使用してソートします。
ソートされた部分配列 | アンソートされていない部分配列 | 配列 |
---|---|---|
( 5 ) | ( 3, 4, 2, 1) | (5, 3, 4, 2, 1) |
- 最初のイテレーション
キー : A[1]
= 3
ソートされた部分配列 | アンソートされていない部分配列 | 配列 |
---|---|---|
( 3 , 5) | (4, 2, 1) | (3, 5, 4, 2, 1) |
- 2 回目のイテレーション
キー : A[2]
= 4
ソートされた部分配列 | アンソートされていない部分配列 | 配列 |
---|---|---|
( 3, 4, 5) | (2, 1) | (3, 4, 5, 2, 1) |
- 3 回目のイテレーション
キー : A[3]
= 2
ソートされた部分配列 | アンソートされていない部分配列 | 配列 |
---|---|---|
( 2, 3, 4, 5) | (1) | (2, 3, 4, 5, 1) |
- 4 回目のイテレーション
キー : A[4]
= 1
ソートされた部分配列 | アンソートされていない部分配列 | 配列 |
---|---|---|
( 1, 2, 3, 4, 5) | () | (1, 2, 3, 4, 5) |
挿入ソートアルゴリズムの実装
#include <iostream>
using namespace std;
void insertion_sort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
int key = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = key;
j--;
}
}
}
int main() {
int n = 5;
int arr[5] = {5, 3, 4, 2, 1};
cout << "Input array: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << "\n";
insertion_sort(arr, n); // Sort elements in ascending order
cout << "Output array: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << "\n";
}
挿入ソートアルゴリズムの複雑さ
時間複雑度
- 平均のケース
平均的には、挿入ソートの ith
パスで i
の比較が行われる。したがって、n 回の繰り返しがある場合、平均的な時間の複雑さは以下のようになります。
1 + 2 + 3 + ... + (n-1) = n*(n-1)/2
したがって、時間の複雑さは [Big Theta]:O(n2)のオーダーです。
- 最悪のケース
最悪の場合は、配列が逆にソートされたときに発生し、最大数の比較とスワップを実行しなければならません。
最悪の場合の時間的複雑さは [Big O]:O(n2)です。
- 最良のケース
最良のケースは、配列が既にソートされているときに、外側のループだけを n 回実行したときです。
最良の時間的複雑さは [Big Omega]: O(n)
です。
空間計算量
挿入ソートアルゴリズムの空間複雑度は、一時変数以外に余分なメモリを必要としないため、O(n)
です。
Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.
LinkedIn