堆的实现

一、二叉树的顺序存储
1.存储方式:
使用数组保存二叉树结构,方式即将二叉树用层序遍历方式放入数组中。一般只适合表示完全二叉树,因为非完全二叉树会有空间的浪费。这种方式的主要用法就是堆的表示。
2.下标关系:
下标从0开始,已知双亲(parent)的下标,则:
左孩子(left)下标 = 2 * parent + 1;
右孩子(right)下标 = 2 * parent + 2;
已知孩子(不区分左右)(child)下标,则:
双亲(parent)下标 = (child - 1) / 2;
二、堆
1.概念:
1.1 堆逻辑上是一棵完全二叉树
1.2堆物理上是保存在数组中
1.3满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆
1.4 反之,则是小堆,或者小根堆,或者最小堆
在这里插入图片描述

三、建堆

import java.util.Arrays;
public class Heap{
    public int[] elem;
    public int usedsize;
    public Heap(){
        this.elem = new int[10];
    }
    //建大堆
    public void buildHeapBig(int[] array){
        for (int i = 0;i < array.length;i++){
            this.elem[i] = array[i];
            this.usedsize++;
        }
        for (int i = (this.usedsize - 1) / 2;i >= 0;i--){
            adjustDownBig(i,this.usedsize);
        }
    }
    //向下调整大根堆
    public void adjustDownBig(int parent,int len){
        int child = (parent * 2) + 1;
        while (child < len){
            if (child + 1 < len && this.elem[child] < this.elem[child + 1]){
                child++;
            }
            if (this.elem[parent] < this.elem[child]){
                int temp = this.elem[child];
                this.elem[child] = this.elem[parent];
                this.elem[parent] = temp;
                parent = child;
                child = (parent * 2) + 1;
            }else{
                break;
            }
        }
    }
    //建小堆
    public void buildHeapSmall(int[] array){
        for (int i = 0;i < array.length;i++){
            this.elem[i] = array[i];
            this.usedsize++;
        }
        for (int i = (this.usedsize - 1) / 2;i >= 0;i--){
            adjustDownSmall(i,this.usedsize);
        }
    }
    //向下调整小根堆
    public void adjustDownSmall(int parent,int len){
        int child = (parent * 2) + 1;
        while (child < len){
            if (child + 1 < len && this.elem[child] > this.elem[child + 1]){
                child++;
            }
            if (this.elem[parent] > this.elem[child]){
                int temp = this.elem[child];
                this.elem[child] = this.elem[parent];
                this.elem[parent] = temp;
                parent = child;
                child = (parent * 2) + 1;
            }else {
                break;
            }
        }
    }
    //判满
    public boolean isFull(){
        if (this.usedsize == this.elem.length){
            return true;
        }
        return false;
    }
    //扩容
    public void increase(){
        this.elem = Arrays.copyOf(this.elem,this.usedsize * 2);
    }
    //入队列
    public void push(int val){
        if (isFull()){
            increase();
        }
        this.elem[this.usedsize] = val;
        this.usedsize++;
        adjustUp(this.usedsize - 1);
    }
    //向上调整(大堆)
    public void adjustUp(int child){
        int parent = (child - 1) / 2;
        while (child > 0){
            if (this.elem[parent] < this.elem[child]){
                int temp = this.elem[parent];
                this.elem[parent] = this.elem[child];
                this.elem[child] = temp;
                child = parent;
                parent = (child - 1) / 2;
            }else {
                break;
            }
        }
    }
    //判空
    public boolean isEmpty(){
        if (this.usedsize == 0){
            return true;
        }
        return false;
    }
    //出队列
    public void pop(){
        if (isEmpty())return;
        int temp = this.elem[0];
        this.elem[0] = this.elem[this.usedsize - 1];
        this.elem[this.usedsize - 1] = temp;
        this.usedsize--;
        adjustDownBig(0,this.usedsize);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值