ヒープソートヒープソートの思想、と個人的な最適化についての講演。(古いもの)

私はあなたがヒープソート億データそれラフトだ聞きますか?

はじめに:さあ、今日は〜、それはそれで使用される大量のデータを行ための比較の基準ソートされると言います

注:フロント用の新しいスキル要件を学ぶためにこの記事を読む:学生の要件を満たしていない場合は、バイナリ配列と本質が何であるかを理解するために火桃の右上隅をお読みください×のようにポイント= - =〜

その前に、我々は最初のマップを見て

ああ、それは楽しみではないでしょうか?このようなものは、ヒープソート(ヒープソート)と呼ばれています

そして、私たちはそれをソート〜に示す動作方法として、伝説のように、今日のこと心配しています

ヒープソートは、つまり、一つのことをやってきたことと呼ばれる、それはエレガントな用語でポイントと呼ばれる:HeapAdjust(最大ヒープを調整)

第1の最大スタックを説明する前に質問、ヒープがそれ何ですか?
砂、マウンド、ヒープ、これらのものの特徴は何ですか、それは?れる
ピラミッドのように、コンテンツが下から上に向かって減少している。そして、私は最大を言いましたヒープは、それはヒープに言うことです
ヒープの最大頂上(値)の値を示し、最大ヒープ内容(砂やキーとして知られている石)、その後、ダウン徐々に減少します。

だから、どのようにこの最大ヒープそれをやりましたか?

私は、Baiduの百科事典バー〜からいくつかのコードを投稿の下に
Baiduの百科事典-ヒープソートを

// array 是待调整的堆数组, i 是待调整的数组元素的位置, length 是数组的长度
// 本函数功能是:根据数组 array 构建大根堆
void HeapAdjust(int array[], int i, int length)
{
    for(int Child, Temp; 2 * i + 1 < length; i = Child)
    {
        //子结点的位置 = 2 *(父结点位置)+ 1
        Child = 2 * i + 1;
        //得到子结点中较大的结点
        if(Child + 1 < length && array[Child + 1] > array[Child]) ++Child;
        //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点
        if(array[i] < array[Child]) Temp = array[i], array[i] = array[Child], array[Child] = Temp; 
        //否则退出循环
        else break;
    }
}
//堆排序算法
void HeapSort(int array[], int length)
{
    int i;
    // 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素
    // length / 2 - 1 是最后一个非叶节点,此处"/"为整除
    for(i = length / 2 - 1; i >= 0; --i) HeapAdjust(array, i, length);
    // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
    for(i = length - 1; i > 0; --i)
    {
        // 把第一个元素和当前的最后一个元素交换,保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
        array[i] ^= array[0], array[0] ^= array[i], array[i] ^= array[0];
        // 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
        HeapAdjust(array, 0, i);
    }
}

= - そこで行われるすべての作業は、私が考える=非常に合理化されたように見えます。

それは我々がそれは〜それを作品と言う方法です

まずヒープソート初めての前処理を行うには、この機能は、仕事の目的は、最大ヒープに調整され、この配列をもたらすことです

その逆実行HeapAdjust

最後から二番目が、開始されていないが、第二層のツリーノードの子ノードの逆数の存在が始まる(長さ/ 2から1)。

それは何を意味するのでしょうか?

HeapAdjustの動作原理であるためです。

和がスワップ(この場合の最大スタック構築物)よりも大きい場合、まず、左右のノードは、大きいノードを選択し、次に親ノードと比較しました。

その後、上記の動作は、現在のサブノードについて繰り返される行います。

まあ、とき逆順ゼロに、本の成功の最大ヒープが今何をすべきか、構築しましたか?

現在知られている条件、これの最大ヒープトップは、それから、最大値と配列交換(境界マイナス1)の最後の要素、
今回の最大ヒープとは、維持する必要があり、その後、どのようにそれを行うには?

今回はすぐにあなたが要素とその境界の位置を調整したいことを伝える必要があり、HeapAdjustの大人を作る必要があります。

、今、ああ、全能HeapAdjust大人のおかげで、この素子電流最大値に再調整を行います。

まあ、それはすべてそこにヒープソートのことを考えています。

これまでのところ、この章が終了した、次は私の個人的な隠されたコンテンツです(/w \)(一部の人は本当にここが表示されます?いいえ私をからかって、右〜)

ここでの学生は、それはここで見ることができるので、私は今、問題の詳細を指して聞かせて、同級生のコンピュータと恋に基本的なものを参照するには-
実際には、コードは非常に低いBaiduの百科事典を提供し、次のようにリリースする予定の私コードそれ〜

    void HeapAdjust(int arr[], int pos, int len)
    {
        int keypos = (pos << 1) + 1, KeyElement = arr[pos];//keypos 为其左子节点位置, KeyElement 为当前需要调整位置的元素.
        while(keypos < len)//检查左子结点是否越界.
        {
            if (keypos + 1 < len && arr[keypos] < arr[keypos + 1]) keypos++;//若右结点存在且比左结点更大则替换
            if (KeyElement > arr[keypos]) break;//若不存在比KeyElement更大的的子结点则中断调整位置
                       arr[pos] = arr[keypos], pos = keypos, keypos = (pos << 1) + 1;//将当前节点覆盖其父节点,同时更新当前结点为其子节点
        }
        arr[pos] = KeyElement;//最后确定位置后归位
    }  

ここに私の改良版である、そして、宇宙N.のさらなる最適化の費用があります

    while (true)
    {
        //因数组数据特殊性,当树结点单枝时一定存在左结点(pos + 1 >= max),则pos不变动
        if(arr[pos] < arr[pos + 1] && pos + 1 < max) pos++;//若右结点存在且大于则替换为右结点
        //将进一步移动到其子节点
        arr[pos - 1 >> 1] = arr[pos], pos = (pos << 1) + 1;
        //left and right node all is zero to break;
        if (pos > max || (!arr[pos] && !arr[pos + 1]))
        {
            //assume zero is side element
            arr[pos - 1 >> 1] = 0;
            break;
        }    
    } 

私はちょっと、改善の原則がある同じことを行うにしてえっ改善するために誰かを見つけるためには至っていない:
ヒープ要素の上部を引き出した場合、より大きな要素の周りに、以下のサブノードを設置し、最後に終了(境界)になります、それは2つのつの子ノード0(側要素)の動作の彼らの子ノードに来るとき0でそれに割り当てられ、この後、さらに調整を中断します。

N(繰り返しHeapAdjustのたくさん)の伝統的な練習よりも理論的には、この犠牲はスペースより経済的な運転、価格がN個のデータを格納するためのスペースの無駄になります。

今のC ++のSTLのソートが何であるかをここで少し言及()
これは、クイックソート、ヒープソート、挿入ソートバインディングを使用し
、一般的な用語のイントロソート(イントロソートを)。

最後に、心からの感謝LYC隊Yの学生は、私と一緒に昼と夜を勉強し、学生はその後、プレイ機Lを行くように、私は、非常に退屈な感じ、と以前にASTAR彼が悪いプレーすると言うでしょう彼と何の参加がないことを、変更することもトス、またはより良いスペースを再生するために彼に自由を与える= - =〜

私はウィキに公開改善コードを作りたかったが、今私はまだ考える人々が一日、それを懸念しているになるまで待ってからかけていないこの空間に残っていることも利用可能= - =〜

2年後、ああ、私は学んだその年には、いくつかの地獄です!

おすすめ

転載: www.cnblogs.com/juwan/p/11449003.html