Java二叉堆的自我调整与排序

二叉堆的定义就不多说了,我们主要介绍二叉堆的自我调整,二叉堆分为最大堆,最小堆。
二叉堆的储存方式是数组,所以其左子下标为 2*parent+1;右子为2*parent+2;
搞明白了这个,首先介绍插入一个数,插入位置是二叉堆最后一个位置;将其排序,
则 我们使用上浮调整最小堆

public static void upAdjust(int[] array) {
        int childIndex = array.length-1;//最后一个子值的下标
        int parentIndex = (childIndex-1)/2;//找到其父值下标
        int temp = array[childIndex]; // temp保存插入的叶子节点值,用于最后的赋值
        while (childIndex > 0 && temp < array[parentIndex])//新值没上升到根或小于父值
        {
            //无需真正交换,单向赋值即可
            array[childIndex] = array[parentIndex];//将父值变成子值
            childIndex = parentIndex;//让子值替代父值,使用交换下标
            parentIndex = (parentIndex-1) / 2;//新的父值
        }
        array[childIndex] = temp;最后跳出循环,放入子值
    }

最大堆的方法同理不过多写了

接下来我们将一个无规则的树进行排列
使用下沉的方法

public static void downAdjust(int[] array, int parentIndex, int length) {//传入数组,父值的下标,数组长度
        int temp = array[parentIndex]; // temp保存父节点值,用于最后的赋值
        int childIndex = 2 * parentIndex + 1;//找到子节点
        while (childIndex < length) {
            // 如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子
            if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex]) {
                childIndex++;
            }
            // 如果父节点小于任何一个孩子的值,直接跳出
            if (temp <= array[childIndex])
                break;
            //无需真正交换,单向赋值即可
            array[parentIndex] = array[childIndex];//将子值变成父值
            parentIndex = childIndex;//让父亲下沉
            childIndex = 2 * childIndex + 1;//子节点向下寻找
        }
        array[parentIndex] = temp;//结束,放入值
    }


    public static void buildHeap(int[] array) {
        // 从最后一个非叶子节点开始,依次下沉调整
        for (int i = (array.length-2)/2; i >= 0; i--) {
            downAdjust(array, i, array.length);
        }
    }

接下来就是总代码了

package tree;

import java.util.Arrays;

public class HeapOperator {
    /**
     * 上浮调整
     * @param array     待调整的堆
     */
    public static void upAdjust(int[] array) {
        int childIndex = array.length-1;
        int parentIndex = (childIndex-1)/2;
        // temp保存插入的叶子节点值,用于最后的赋值
        int temp = array[childIndex];
        while (childIndex > 0 && temp < array[parentIndex])
        {
            //无需真正交换,单向赋值即可
            array[childIndex] = array[parentIndex];
            childIndex = parentIndex;
            parentIndex = (parentIndex-1) / 2;
        }
        array[childIndex] = temp;
    }

    /**
     * 下沉调整
     * @param array     待调整的堆
     * @param parentIndex    要下沉的父节点
     * @param length    堆的有效大小
     */
    public static void downAdjust(int[] array, int parentIndex, int length) {
        // temp保存父节点值,用于最后的赋值
        int temp = array[parentIndex];
        int childIndex = 2 * parentIndex + 1;
        while (childIndex < length) {
            // 如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子
            if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex]) {
                childIndex++;
            }
            // 如果父节点小于任何一个孩子的值,直接跳出
            if (temp <= array[childIndex])
                break;
            //无需真正交换,单向赋值即可
            array[parentIndex] = array[childIndex];
            parentIndex = childIndex;
            childIndex = 2 * childIndex + 1;
        }
        array[parentIndex] = temp;
    }

    /**
     * 构建堆
     * @param array     待调整的堆
     */
    public static void buildHeap(int[] array) {
        // 从最后一个非叶子节点开始,依次下沉调整
        for (int i = (array.length-2)/2; i >= 0; i--) {
            downAdjust(array, i, array.length);
        }
    }

    public static void main(String[] args) {
        int[] array = new int[] {1,3,2,6,5,7,8,9,10,0};
        upAdjust(array);
        System.out.println(Arrays.toString(array));

        array = new int[] {7,1,3,10,5,2,8,9,6};
        buildHeap(array);
        System.out.println(Arrays.toString(array));
    }
}

结果分别是 [0, 1, 2, 6, 3, 7, 8, 9, 10, 5] 和[1, 5, 2, 6, 7, 3, 8, 9, 10]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值