算法__堆排序

二叉堆 是一种完全二叉树,堆可以分为最大堆和最小堆。最大堆:父节点的值都大于两子节点的值;最小堆:父节点的值都小于子节点的值。

图中就是一个最大堆

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;
    }

 

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