学习笔记:堆排序

Posted arseneyao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习笔记:堆排序相关的知识,希望对你有一定的参考价值。

一、定义

①堆通常是可被视为完全二叉树的数组。

②堆中任意节点的数值总是大于或等于其左右子节点,为大根堆。

③堆中任意节点的数值总是小于或等于其左右子节点,为小根堆。

 

二、存储

对于任意节点T[i]

①若其父节点存在,为T[(i - 1) / 2]

②若其左兄弟节点存在,为T[i - 1]

③若其右兄弟节点存在,为T[i + 1]

④若其左子节点存在,为T[i * 2 + 1]

⑤若其右子节点存在,为T[i * 2 + 2]

 

数组表示

技术分享图片

二叉树表示

 技术分享图片

 

三、调整(大根堆)

①若数值大于选择节点的左右子节点存在,则交换选择节点与左右子节点中数值较大者。

②若数值大于选择节点的左右子节点不存在,则该选择节点的调整结束。

 

具体过程如下:

假设选择根节点进行调整。

技术分享图片

将选择节点与数值较大的右子节点进行交换。至此调整结束,不存在大于选择节点的左右子节点。

技术分享图片

 

四、排序

①构建大根堆。从最后一个非叶节点开始,从下到上、从右到左选择每个非叶节点进行一次调整。

②调整堆结构。从最后一个节点开始,从下到上、从左到右将每个节点与根节点进行交换后,选择根节点进行一次调整。已经与根节点交换过的位置不参与调整。

 

具体过程如下:

选择7进行调整。

技术分享图片

选择5进行调整。

技术分享图片

选择6进行调整。

技术分享图片

交换1和7,选择根节点1进行调整。

虽然7大于2,但7所处的位置已与根节点进行过交换,所以不参与调整。

技术分享图片

交换1和6,选择根节点1进行调整。

技术分享图片

交换3和5,选择根节点3进行调整。

虽然5大于3,但5所处的位置已与根节点进行过交换,所以不参与调整。

技术分享图片

交换1和4,选择根节点1进行调整。

技术分享图片

交换2和3,选择根节点2进行调整。

技术分享图片

交换1和2,选择根节点1进行调整。

技术分享图片

排序结束,二叉树对应的数组有序。

 

五、实现

public class HeapSort {
    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    private static void adjust(int[] array, int i, int length) {
        int temp = array[i];
        for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
            if (j + 1 < length && array[j] < array[j + 1])
                j = j + 1;
            if (array[j] > temp) {
                array[i] = array[j];
                i = j;
            } else break;
        }
        array[i] = temp;
    }

    public static void sort(int[] array) {
        for (int i = (array.length - 1) / 2; i >= 0; i--)
            adjust(array, i, array.length);
        for (int j = array.length - 1; j > 0; j--) {
            swap(array, 0, j);
            adjust(array, 0, j);
        }
    }
}

 

以上是关于学习笔记:堆排序的主要内容,如果未能解决你的问题,请参考以下文章

数据结构学习笔记——选择排序(简单选择排序和堆排序)

数据结构学习笔记——选择排序(简单选择排序和堆排序)

堆排序学习笔记

数据结构学习笔记——选择排序(简单选择排序和堆排序)

学习笔记:堆排序

数据结构学习笔记-排序/队/栈/链/堆/查找树/红黑树