アルゴリズム - C 言語はシェル ソート (Shell_sort) を実装します。

目次

ヒルソートとは何ですか?

ヒルソートの使用シナリオ:

ソート間の比較による Hill ソートを導入します。

ヒルソートのプロセスをデモンストレーションします。

最初のパスを並べ替えます。

2 番目の並べ替え:

3 番目の並べ替え:

4 番目の並べ替え:

プログラムの検証:

コード:

現実のヒルソーティング:

ヒルソートの概要:


ヒルソートとは何ですか?

Hill ソートのコードを記述する前に、Hill ソートのソート原理と定義を整理しましょう。

シェルのソートは縮小増分ソートとも呼ばれ、挿入ソート カテゴリに属する​​方法ですが、前述のトータル ソート方法よりも時間効率が大幅に向上します。ヒル ソートの基本的な考え方は、まずソート対象のレコードのシーケンス全体をいくつかの単語シーケンスに分割し、それぞれ直接挿入ソートを実行します。次に、シーケンス全体のレコードが「」の場合、すべてのレコードに対して直接挿入ソートを実行します。基本的には順番どおりです。」

ヒルソートは挿入ソートの最適化に相当します.以前の記事C言語での挿入ソートの実装で述べたように, 挿入ソートはシーケンスの一部がすでに順序付けられているソートです.挿入ソートは順序が整っていればいるほど,効率を高める

ヒルソートの使用シナリオ:

ヒル ソートは、中規模のデータ ボリュームのソートに適しています。

ソート間の比較による Hill ソートを導入します。

たとえば、ここではシーケンスが与えられています。

int ar[5] = {1,2,3,4,0};

 このときバブルソートを使用すると、要素0が先頭に来るまでの合計実行回数は4回となり、各回の実行順序は次のようになります。

{1,2,3,0,4};
{1,2,0,3,4};
{1,0,2,3,4};
{0,1,2,3,4};

しかし、挿入ソートを使用すると効率が大幅に向上し、要素 0 を先頭に配置できるのは 1 回だけになります。 

まず、添字が 0 番目の要素に到達するまで配列をスキャンしますが、後者が前者より大きいという規則を満たさないため、この時点で temp に 0 を代入し、以前にソートされたシーケンスと比較します。小さいほうがよいので、要素 1、2、3 を 1 ビット後ろに移動し、0 を前に置きます。

{0,1,2,3,4};

ヒル ソートに戻りましょう。ヒル ソートは、挿入ソートの最適化と同等です。挿入ソートには、バブル ソートや選択ソートより明らかな利点がありますが、シーケンス内にソートが必要な要素が多数ある場合、毎回毎回隣接する要素と比較するのは少し複雑ですが、ヒル ソートはこの複雑さを解決するように設計されています。

ヒルソートのプロセスをデモンストレーションします。

図に示すように、配列を与えます。

{10,11,13,5,0,13,2,7,8,6,0};

最初のパスを並べ替えます。

次に、製図板上での Hill ソートのプロセスを示します。

2 番目の並べ替え:

並べ替えの増分をシーケンス全体の長さとして定義し、それを直接比較します。10 > 0 であることがわかり、2 つの要素の位置が交換され、次の並べ替えでは並べ替えの増分が元の半分に減ります。

ギャップ値を整数値の形式で定義しているため、要素数は 11 で、11 / 2 は 5.5 です。ここでは、ギャップ値をそのまま 5 として、11 > 2、13 > 7 がわかります。 , 13 > 10, したがって、これら 6 つの要素の位置が入れ替わります。図の下の部分は、2 回目のソート後の要素の順序: 0 2 7 5 0 10 11 13 8 6 13 です。

3 番目の並べ替え:

このとき、ギャップの値は 2 回目の半分になります: 5 / 2 = 2.5。ここではギャップの値は 2 です。

7 > 0、13 > 11 > 8、これら 6 つの要素の位置が交換され、図の下の部分が 3 回目の並べ替え後の要素であることがわかりました: 0 2 0 5 7 6 8 10 11 13 13

4 番目の並べ替え:

このとき、gap の値は 1 となり、直接挿入ソートと同等になります。4 回目のソート結果も最終的なソート結果となります。2 > 0、7 > 6 であることがわかり、これらの位置を入れ替えます。 4 つの要素と並べ替え 最終結果は次のようになります: 0 0 2 5 6 7 8 10 11 13 13

プログラムの検証:

図に示すように、11 個の数値が正常にソートされています。

コード:

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
#define MAXSIZE 11
void initar(int *ar,int len)
{
	assert(ar != nullptr);
	for(int i = 0;i < len;i++){
		ar[i] = rand() % 20;
	}
}
void showar(int *ar,int len)
{
	assert(ar != nullptr);
	for(int i = 0;i < len;i++){
		printf("%d ",ar[i]);
	}
	printf("\n--------------------------\n");
}
void Shell_sort(int *ar, int len) {
	assert(ar != nullptr && len >= 0);
	int i = 0,j = 0;
	int temp = 0;//定义中间值用于存储数据
	int gap = 0;//定义排序增量
	gap = len;//将排序增量的初始值直接设置为数组的长度
	while(gap > 1){
		gap /= 2;
		for(i = gap;i < len;i += gap){
			if(ar[i] < ar[i - gap]){
				temp = ar[i];
				for(j = i - gap;j >= 0 && ar[j] > temp;j -= gap){
					ar[j + gap] = ar[j];
				}
				ar[j + gap] = temp;
			}
		}
	}
}
int main()
{
	srand((unsigned int)time(NULL));
	int ar[MAXSIZE];
	initar(ar,MAXSIZE);
	printf("原始数据为:\n");
	showar(ar,MAXSIZE);
    printf("\n经过希尔排序后的数据为:\n");
	Shell_sort(ar,MAXSIZE);
	showar(ar,MAXSIZE);
}

コンピュータがランダムに生成した20個以下の12個の数値を使って、並び替えにヒルソートを使ってみましょう 関数のforループの3層目の最後にdisplay array文を追加して、それぞれに配列全体を出力しますソートパスの結果を見てみましょう:

図に示すように、ヒル ソートを使用して合計 4 回 (ギャップの値を 4 回変更する) ソートを実行し、最終的にシステムがランダムに生成したデータの昇順ソートを完了しました。 

現実のヒルソーティング:

私たちは皆、ポーカーをプレイしたことがあります。たとえプレイしたことがなくても、他の人がポーカーをプレイしているのを見たことがあるでしょう。ポーカーのデッキは購入するときはすべて新品であり、小さいものから大きいものまでさまざまなスーツに応じて分類されています。ソートプロセス これは単純なヒルソートと考えてください。

54 枚のトランプを小さいものから大きいものまで並べ替える前に、まずトランプをクラブ、ダイヤ、スペード、ハートに対応する異なるスートに従って 4 つのグループに分割する必要があります。そうすれば、現在の並べ替えの増分は次のようになります。 4. 次に、13 個の数字を小さい順から大きい順にソートします (ソート単位は 1、ソート方法は直接挿入ソートです)。

したがって、トランプのソートは単純なヒルソートとみなすことができ、ソートの増分は 4 から 1 に変化し、2 回のパスの後、最終的にソートが完了します。

ヒルソートの概要:

ヒル ソートの時間計算量はソート増分 (ギャップ) に応じて変化します。時間計算量は O(nlogn) ~ O( ) の間で変化し、空間計算量は常にn^{2}O(1) です。ヒル ソーティングは不安定なアルゴリズムです。

ヒルソートの実行順序は、ソート増分が減少し、増分が 1 になったら直接挿入ソートを実行します。

一時変数のみを保存する必要があるため、空間複雑度は O(1) です。

ヒル ソートは不安定なアルゴリズムです。ソートの増分により、シーケンスは異なるシーケンスに分割されますが、これにより、同じ要素の相対位置が変化する可能性があります。たとえば、奇数のシーケンス {4,5,3,2,1このときのソート増分(ギャップ)の値が2の場合、最後の要素1の相対位置が変わります。

おすすめ

転載: blog.csdn.net/weixin_45571585/article/details/125975529#comments_27891441