ヒープの並べ替えにおける各ヒープ調整の順序

ヒープの並べ替え(ヒープの並べ替え)は、単純な選択の並べ替えの改善です。改善の焦点は、レコード比較の数を減らす方法です。単純選択ソートでは、ソートパスの最小レコードのみが選択され、パスの比較結果は保存されないため、レコードの比較時間は長くなります。最小のレコードを選択している間、ヒープの並べ替えは小さいレコードも検出するため、選択される比較の数が減り、並べ替え全体の効率が向上します。ヒープソートアルゴリズムの基本的な考え方は次のとおりです。
最初に、大きなルートヒープにソートされるシーケンスを構築します。つまり、ヒープ内のすべてのレコードのうち最大のものを選択し、それをヒープから削除して、残りのレコードをヒープに調整します。ヒープにレコードが1つだけになるまで、次に小さいレコードを探していきました。
ここで、小さなヒープから大きなヒープへのソートプロセス中に、各ヒープ調整(初期ヒープの構築を含む)後のヒープの順序を計算したいと考えています。
ここに画像の説明を挿入
[入力形式]
1行目の整数N、2行目のN整数、順序付けなし。0 <N <= 100
【出力形式】
N行の出力を出力します。i番目の行は、i番目のヒープ調整後のN-i + 1整数の順序に対応します。
【入力例】
5
2 3 1 5 4
【出力例】
5 4 1 3 2
4 3 1 2
3 2 1
2 1
1

分析:
ヒープの並べ替えでは、完全なバイナリツリーの性質を使用して、大きなルートヒープ(小さなルートヒープ)を構築し、最大(最小)のルートノードを配置して、ルートノードを最後のノードと交換します。この値
は、本質的に大きなルートヒープ(小さなルートヒープ)を構築することですルートヒープ)メソッド、最大(最小)値を見つけ、最後のノードと交換して並べ替えます

ヒープを構築する機能

void adjust(int arr[],int n,int i)
{
    int left=i*2+1;//下标为i的左孩子
    int right=i*2+2;//下标为i的右孩子
    int maxi = i;
    if(left<n&&arr[left]>arr[maxi])
        maxi=left;
    if(right<n&&arr[right]>arr[maxi])
        maxi=right;
    if(maxi!=i)//当下标为i 的结点不是它和它孩子节点中最大数时
    {
        swap(arr[maxi],arr[i]);
        adjust(arr,n,maxi);
    }
}

出力ヒープをソートする関数

void heapSort(int arr[],int n)
{
    for(int i=n/2-1;i>=0;i--)//从第一个非叶子结点开始
    {
        adjust(arr,n,i);//初始建堆
    }
    for(int i =0;i<n;i++)
    {
        cout<<arr[i]<<" ";
    }
    cout<<endl;
    for(int i=n-1,j=n-1;i>=1;i--,j--)//经过初始建堆后 还需n-1次建堆
    //每次最大的在树的根节点上
    {
        swap(arr[0],arr[i]);//把根节点和最后一个结点交换
        adjust(arr,i,0);//继续进行排堆 从下标为0的结点开始 对剩下的i个进行堆排序
        for(int i=0;i<j;i++)
        {
            cout<<arr[i]<<" ";//输出堆排序后每次堆调整后的次序
        }
        cout<<endl;
    }
}

主な機能

int main()
{
    int n;
    cin>>n;
    int arr[n];
    for(int i=0;i<n;i++)
    {
        cin>>arr[i];
    }
    heapSort(arr,n);
}

以下は少し白いですが、不適切な箇所がある場合は修正してください。

公開された31元の記事 ウォンの賞賛8 ビュー2155

おすすめ

転載: blog.csdn.net/weixin_44034024/article/details/105242476