ヒルソーティングに関する洞察 (チャレンジプログラミング 2 を参照)
いわゆるヒルソートとは、挿入ソートを用いて大規模なデータのソートを処理するアルゴリズムです。挿入ソートはデータを比較的整った順序で高速に処理することができ、ヒルソートはまさに挿入ソートの特徴です。たぶん私自身の名前です)、最初に順序のない数値をより整然とした方法で配置し、次に挿入ソートによってデータを配置するという目的を達成します。
以下はコードです
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
long long cnt;
int A[100000];
int n;
vector<int> G;
void insertionSort(int A[], int n, int g)
{
for (int i = g; i < n; i++)
{
int v = A[i];
int j = i - g;
while (j >= 0 && A[j] > v)
{
A[j + g] = A[j];
j -= g;
cnt++;
}
A[j + g] = v;
}
}
//生成希尔数列
void shellSort(int A[], int n)
{
for (int h = 1;;)
{
if (h > n) break;
G.push_back(h); //在G的后面添加一个元素
h = h * 3 + 1;
}
for (int i = G.size() - 1; i >= 0; i--) //G.size()表示获取G的元素个数
{
insertionSort(A, n, G[i]);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) scanf("%d", &A[i]);
cnt = 0;
shellSort(A, n);
cout << G.size() << endl;
for (int i = G.size() - 1; i >= 0; i--)
{
printf("%d", G[i]);
if (i) printf(" ");
}
printf("\n");
printf("%d\n", cnt);
for (int i = 0; i < n; i++)
{
printf("%d \n", A[i]);
}
}
コード分析
まず、n から cin までの値を入力し、次に for ループを使用してデータを読み取ります。入力には高速な scanf 関数を使用します。
次に、shellSort 関数を呼び出します。
A のアドレスと A の長さは、shellSort 関数に渡されます。最初の for ループは、Hill 配列を生成するために使用されます。
h は 1 から始まり、Vector の Push_back 関数を使用して G の最後の項目に追加または追加し、h が n より大きい場合にループから抜け出します。ヒルシーケンスが生成されます。
次に、2 番目の for ループで insertSort 関数が呼び出され、Hill シーケンスの数値が後から関数に渡されます。
次に、挿入並べ替えで並べ替えます。