C# はヒル ソートを実装します

C# はヒル ソートを実装します

プロセス解体

次のように、既存の配列があるとします。

ここに画像の説明を挿入
基本的な並べ替えコードは次のとおりです。

static void Main(string[] args)
{
    
    
    int[] array = new int[] {
    
     5, 4, 5, 2, 3, 6, 1 };//替换代码
    BaseSort(array, 3);//替换代码
    for (int i = 0; i < array.Length; i++)
    {
    
    
        Console.Write(array[i] + " ");
    }
    Console.ReadKey();
}
public static void BaseSort(int[] array, int gap)
{
    
    
    for (int i = gap; i < array.Length; i++)
    {
    
    
        int insertValue = array[i];
        for (int j = i - gap; j >= 0; j -= gap)
        {
    
    
            if (insertValue < array[j])
            {
    
    
                array[j + gap] = array[j];
                array[j] = insertValue;
            }
            else
            {
    
    
                break;
            }
        }
    }
}
  1. 置換コードを次のコードに置き換え、実行して分析します
int[] array = new int[] {
    
     5, 4, 5, 2, 3, 6, 1 };
BaseSort(array, 3);
//将下标差值为 3 的一组数进行排序

添字3 で前方に 3 の間隔で添字0 を見つけ、挿入ソート アルゴリズムを使用してソートします。

ここに画像の説明を挿入
subscript 4 forwardで間隔が 3 のsubscript 1 を見つけ、挿入ソート アルゴリズムを使用してソートします。添字 5で前方に 3 の間隔で添字2 を見つけ、挿入ソート アルゴリズムを使用してソートします。添字 6 前方に3 間隔で添字3と添字 0を見つけ、このとき添字 0 と添字 3 がソートされていることを確認し、挿入ソート アルゴリズムを使用してソートします。
ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

  1. 置換コードを次のコードに置き換え、実行して分析します
int[] array = new int[] {
    
     1, 3, 5, 2, 4, 6, 5 };
BaseSort(array, 1);
//将下标差值为 1 的一组数进行排序

添え字1 から1 間隔で添え字0 を見つけ、挿入ソート アルゴリズムを実行して並べ替えます。添字 1 から 1間隔添字1 と添字 0 を求め、ソートには挿入ソートアルゴリズムを実行します。添字1 前方、添字 2、添字 1、添字 0 で間隔 1 の求め、ソートには挿入ソート アルゴリズムを実行します。添字 1前方、添字 3、添字 2、添字 1、添字 0 の間隔が 1 の見つけ、ソートには挿入ソート アルゴリズムを実行します。添字 1前方、添字 4、添字 3、添字 2、添字 1、添字 0の間隔が 1見つけ、ソートには挿入ソート アルゴリズムを実行します。添字1 前方、添字 5、添字 4、添字 3、添字 2、添字 1、添字 0の間隔が 1を求め、ソートには挿入ソート アルゴリズムを実行します。
ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

アルゴリズムの実装

  1. ヒル ソートは、グループソートに間隔を使用し直接挿入ソート アルゴリズムを最適化します
  2. 配列の長さの半分を初期間隔の長さとして選択し、それらを並べ替えます。その後、ループは間隔としてn/2を取ります。
  3. 可能な限り、最後の直接挿入ソートの時間アルゴリズムの複雑さを O(n) とします。

コードは以下のように表示されます

static void Main(string[] args)
{
    
    
    int[] array = new int[] {
    
     5, 4, 5, 2, 3, 6, 1 };
    ShellSort(array);
    for (int i = 0; i < array.Length; i++)
    {
    
    
        Console.Write(array[i] + " ");
    }
    Console.ReadKey();
}
public static void ShellSort(int[] array)
{
    
    
    for (int gap = array.Length / 2; gap > 0; gap /= 2)
    {
    
    
        //直接插入排序算法
        for (int i = gap; i < array.Length; i++)
        {
    
    
            int insertValue = array[i];
            for (int j = i - gap; j >= 0; j -= gap)
            {
    
    
                if (insertValue < array[j])
                {
    
    
                    array[j + gap] = array[j];
                    array[j] = insertValue;
                }
                else
                {
    
    
                    break;
                }
            }
        }
    }
}

分割コードは以下の通り

public static void ShellSort(int[] array)
{
    
    
    for (int gap = array.Length / 2; gap > 0; gap /= 2)
    {
    
    
        InsertSort(array, gap);
    }
}

public static void InsertSort(int[] array, int gap)
{
    
    
    for (int i = gap; i < array.Length; i++)
    {
    
    
        int insertValue = array[i];
        for (int j = i - gap; j >= 0; j -= gap)
        {
    
    
            if (insertValue < array[j])
            {
    
    
                array[j + gap] = array[j];
                array[j] = insertValue;
            }
            else
            {
    
    
                break;
            }
        }
    }
}

複雑さと安定性

ここに画像の説明を挿入

  • 最適な時間の複雑さ:間隔が 1 で順序が並べ替えられている場合、挿入並べ替えの最初の for ループのみを経験する必要があります。
  • 最悪の時間の複雑さ: 配列が逆順の場合、挿入ソートの 2 番目の for ループの実行回数は、Hill ソートの間隔演算の後に減らすことができます。したがって、実際のソート時間は、直接挿入ソートの最悪の時間の複雑さと同じです。
  • 平均時間の複雑さ: 主に間隔の値に依存します
  • スペースの複雑さ: insertValue 変数を使用して、比較のために値を記録する必要があります
  • 安定性: ソートアルゴリズムの後、以前の値は後ろにランク付けされます (例: 5)

著者のエネルギーが限られているため、記事には間違いや脱落が避けられませんが、専門家やネチズンは私を批判して修正することを歓迎します。

おすすめ

転載: blog.csdn.net/qq_46051312/article/details/126299937
おすすめ