数据结构与算法分析:最大堆(概念)

这篇文字只方便已经了解最大堆,但又忘记最大堆怎么操作的人回忆

定义

  1. 父节点一定大于或者等于子节点
  2. 一般使用数组来表示二叉树

概念

上浮(shift Up)

我们将数值和父元素对比,如果大于父元素,则交换,直到小于父元素位置

下沉(Shift Down)

将当前节点的值和孩子节点中较大的节点交换,直到不能交换为止

操作

构建堆(方法1)

  1. 从第二个元素开始
  2. 对每个元素进行上浮操作

构建堆(方法2,建议)

  1. 从第最后一个不是叶子节点的元素开始
  2. 对元素进行下层操作
  3. 移动到前一个元素

插入元素

  1. 将新元素放置到末尾
  2. 然后进行上浮

取出最大元素

  1. 取出最大元素(根节点)
  2. 将末尾的值移动到根节点
  3. 然后将最大元素进行下层

代码

下面我实现的是最小堆,最大堆大家可以自己尝试

public class MinHeap {

    int[] nums = new int[1690 * 3];
    int length = 0;//长度


    public static void main(String[] args) {
        MinHeap minHeap = new MinHeap();
        minHeap.add(1);
        minHeap.add(2);
        minHeap.add(3);
        minHeap.add(5);
        minHeap.add(4);
        minHeap.add(6);
        minHeap.add(10);
        minHeap.add(9);
        minHeap.add(15);
        while (minHeap.length > 0) {
            System.out.println(minHeap.get());
        }
    }

    /**
     * 用方法二进行创建
     */
    public void create(){
        //找到最后一个非叶子节点,即:最后一个元素的父元素
        int fIndex = getFIndex(length - 1);
        for (int i = fIndex; i >= 0 ; i--) {
            shiftDown(i);
        }
    }
    public void add(int cur){
        if(cur < 0){
            return;
        }
        nums[length] = cur;
        length++;
        shiftUp(length-1);
    }

    public int get(){
        if(length == 0){
            new ArrayIndexOutOfBoundsException();
        }
        int max = nums[0];
        length--;
        nums[0] = nums[length];
        shiftDown(0);
        return max;
    }

    /**
     * 上浮
     * @param curIndex
     */
    private void shiftUp(int curIndex){
        if(curIndex == 0){
            return;
        }
        int fIndex = getFIndex(curIndex);
        if(nums[curIndex] < nums[fIndex]){
            int temp = nums[curIndex];
            nums[curIndex] = nums[fIndex];
            nums[fIndex] = temp;
            shiftUp(fIndex);
        }
    }

    /**
     * 下沉
     * @param curIndex
     */
    private void shiftDown(int curIndex){
        int lChildIndex = getLCIndex(curIndex);
        if(lChildIndex >= length){ //说明没有子节点了
            return;
        }
        int rChildIndex = getRCIndex(curIndex);
        int minChildIndex = 0;
        if(rChildIndex >= length){  // 如果右子节点已经越界
            minChildIndex = lChildIndex;
        } else if(nums[lChildIndex] < nums[rChildIndex]){ //如果 “左子节点”  小于  “右子节点”
            minChildIndex = lChildIndex;
        } else {
            minChildIndex = rChildIndex;
        }

        if(nums[curIndex] > nums[minChildIndex]){
            int temp = nums[curIndex];
            nums[curIndex] = nums[minChildIndex];
            nums[minChildIndex] = temp;
            shiftDown(minChildIndex);
        }
    }

    /**
     * 得到父节点的下标
     * @param curIndex
     * @return
     */
    private int getFIndex(int curIndex){
        return (curIndex -1) / 2;
    }

    /**
     * 得到左子节点的下标
     * @param curIndex
     * @return
     */
    private int getLCIndex(int curIndex){
        return curIndex*2 + 1;
    }

    /**
     * 得到右子节点的下标
     * @param curIndex
     * @return
     */
    private int getRCIndex(int curIndex){
        return curIndex*2 + 2;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法分析:C语言描述清晰版》是由美国著名计算机科学家Mark Allen Weiss所著,是一本介绍数据结构算法的经典教材之一。该书内容丰富、深入浅出,既有基础知识的讲解,也有高级算法的探讨,适合计算机科学及其他相关专业的学生、计算机编程爱好者、程序员等人群。 本书主要内容包括线性结构、递归、树、排序和搜索算法、散列表、图等多个章节。其中,线性结构是数据结构的基础,包括线性表、栈、队列等数据结构的实现和操作。递归是一种特殊的函数调用方式,在算法设计中应用广泛,本书详细讲解了递归的原理和应用。树是一种重要的非线性数据结构,本书介绍了二叉树、堆、AVL树等多种树形结构的实现和应用。排序和搜索算法是解决各种实际问题的重要工具,本书详细讲解了冒泡排序、插入排序、归并排序、快速排序等多种排序算法及二分查找、哈希表查找等多种搜索算法。散列表是一种实现高效查找的数据结构,本书深入浅出地讲解了散列表的实现原理和应用。图是一种复杂的数据结构,在算法设计中具有很高的应用价值,本书介绍了图的表示方法、遍历方法和最短路径算法等多个方面的内容。 总的来说,《数据结构与算法分析:C语言描述清晰版》是一本综合性的计算机科学教材,既适合初学者入门学习,也适合中高级程序员深入研究。本书内容翔实,全面而深入,不仅介绍了数据结构算法的基本知识,还讲解了实践中的应用技巧和注意事项,对于从事计算机科学相关领域的人员来说,具有很高的实用价值和参考意义。如果你想在数据结构算法方面有更深入的了解,那么这本书绝对是你不可错过的参考资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值