算法__堆排序

二叉堆 是一種完全二叉樹,堆可以分爲最大堆和最小堆。最大堆:父節點的值都大於兩子節點的值;最小堆:父節點的值都小於子節點的值。

圖中就是一個最大堆

1.那一組數據如何成爲一個最大堆呢

7 1 3 10 5 2 8 9 6

  先將它弄成二叉樹看看:

我們先看一下  10這個數字,它比它的子節點都大,但是大於父節點。所以,我們得將  10 與  1 互換,然後 10再和它的父節點比較,10 大於7 ,10和7交換。10 這個樹中最大的數字就到了根節點了。

同時我們會發現:

 子節點的座標 = 父節點的座標 * 2  +  1;

 子節點的座標 = 父節點的座標 *  2  +  2;

 葉子節點的個數 > 整體節點的一半。

因此:要將無序的樹變成最大堆,只需要將每個父節點和它的子節點比較,保證父節點大於自己的子節點。

代碼如下:

 private void downJust(int[] arrays, int parentIndex, int length) {
        int childIndex = 2 * parentIndex + 1;
        int parentNumber = arrays[parentIndex];
        while (childIndex <= length) {
            if (childIndex + 1 <= length && arrays[childIndex + 1] > arrays[childIndex]) {
                childIndex++;
            }

            if (parentNumber > arrays[childIndex])
                break;

            arrays[parentIndex] = arrays[childIndex];
            parentIndex = childIndex;
            childIndex = parentIndex * 2 + 1;
        }
        arrays[parentIndex] = parentNumber;
    }

    private void build(int arrays[]) {
        for (int i = arrays.length / 2; i >= 0; i--) {
            downJust(arrays, i, arrays.length - 1);
        }
    }

最終的最大堆:

數組:

10 7 8 9 5 2 3 1 6

2.  最大堆建好了,如何堆排序呢?

     (1)最大堆的第一個數總是這組數據中,最大的數。

     (2)將最後數子和最大數交換,然後,將這個數下沉;

   (3)然後將6和自己的子節點下沉,直至比所有子節點都大。

   (4)這時候,8就是最大的,再將8和1交換,1做下沉。就這樣,直到數組排好。

代碼如下:

private int[] heapSort(int[] ss) {
        int size = ss.length - 1;
        build(ss);

        while (size > 0) {
            ss[0] ^= ss[size];
            ss[size] ^= ss[0];
            ss[0] ^= ss[size];
            downJust(ss, 0, size - 1);
            size--;
        }

        return ss;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章