数据结构之优先队列的二叉堆 Java实现

优先队列之二叉堆

什么是优先队列呢?优先队列顾名思义它是一种队列,但是是优先的那种,那么他优先在哪了?
他像我们普通的queue一样一个地方输入,在另一端输出,但是他的输出却是输出最小的
也就是说,优先队列的工作原理是删除并返回优先队列中最小的元素。
如图在这里插入图片描述

二叉堆

什么是二叉堆呢?首先我们需要知道优先队列他又称之为堆,二叉堆也就是像一个被完全填满的二叉树,也就是我们所说的完全二叉树。二叉堆他并不是二叉查找树,但是又类似于二叉查找树,他要求子节点的值得大于父节点的值,也就是说对于每一个节点都成立。而他们的兄弟节点大小顺序无关。
在这里插入图片描述
由此可知,但凡我们想找最小的,只用输出根节点即可!!

二叉堆算法实现

初始化,提供两个构造方法供用户使用。

public class MyBinaryHeap<AnyType extends Comparable<? super AnyType>> {
    //init items
    private int currentSize;
    private AnyType[] myArray;
    private static final int DEFAULT_SIZE=10;
    //init program
    public MyBinaryHeap(){this(DEFAULT_SIZE);}
    public MyBinaryHeap(int defaultSize) {
        currentSize=0;
        //always have a node to operate
        myArray= (AnyType[]) new Comparable[defaultSize+1];
    }

在这里在提供一个构造方法可以让用户直接输入一个任意类型的数组

    //provide a method to add array
    public MyBinaryHeap(AnyType[] inArray){
        currentSize=inArray.length;
        myArray= (AnyType[]) new Comparable[(currentSize*2)*11/10];
        int i=1;
        for(AnyType item:inArray)
            myArray[i++]=item;
        buildHeap();
    }

buildHeap是建立二叉堆,根据用户提供的初始数据,进行排列操作

    //make the array become a BinaryHeap
    private void buildHeap(){
        for (int i = 0; i <currentSize ; i++)
            initNode(i);
    }
    //basic methods size empty and so on
    public int size(){return currentSize;}
    public boolean isEmpty(){return size()==0;}
    public void makeEmpty(){currentSize=0;}

插入

首先我们需要了解二叉堆的插入操作,假设当前已经有了一个二叉堆,而你需要往里面插入一个数据,为了不破坏他的结构,你会怎么做?
我们是不是会想到在最后那个位置进行插入
对,我们在最后那个位置进行插入但是如何使插入之后的又变成二叉堆呢?

上滤

这就需要我们了解一个概念叫做上滤。所谓的上滤就是让当前节点不停的根父节点进行比较,如果当前节点小于父节点,那就把父节点的值放进当前节点中,当然当前节点的值应该提前被一个变量保存。直到找到父节点小于你要插入的这个值或找到0号位置,则把他的孩子节点赋上该值或把根节点赋上该值。
如图在这里插入图片描述

	 /*
    // 从最底下建立一个新的节点,跟他的父节点进行比较,
    // 若小于则把新节点的位置赋上父结点的值
    // 然后hole的位置修正为父的位置继续比较直到hole为根节点的位置结束
    // 这个操作被称为上滤
     */
    //insert
    public void insert(AnyType x){
        int temp=++currentSize;
        myArray[0]=x;//把最后位置的值赋上x
        for(;temp>0;temp/=2 ){//上滤操作
            if (x.compareTo(myArray[temp/2])<0)//与父节点进行比较 若小于父节点  若插入为第一个数据所以要保证0这个位置有值
                myArray[temp]=myArray[temp/2];//把父节点的值给子节点
            else
                break;
        }
        myArray[temp]=x;
    }

删除最小的

根插入一样删除最小的也用到一个叫做下滤的操作,顾名思义也就是跟上滤反着来,原理是一样的。
在我们删除最小的时候,把最后一个元素赋给根节点,然后从根节点开始下滤操作最终得到一个二叉堆。

    //deleteMin
    public AnyType deleteMin(){
        AnyType x=findMin();
        myArray[1]=myArray[currentSize--];//把最后的元素赋予第一个位置
        initNode(1);
        return x;
    }
    //find Min
    public AnyType findMin(){return myArray[1];}
     /*
    //从根节点开始,往下找,找到比temp小的就把他往上放
    //如果该节点有两个孩子节点,则比较两个孩子节点的大小,把小的拿来跟父节点比较
    //如果孩子节点比temp节点大了,则把父节点设为temp 结束
    //这个过程称为下滤
     */
    //init node
    private void initNode(int location){
        int child_L;
        AnyType x=myArray[location];//记录当前位置的数据
        for (;location*2<currentSize;location=child_L){
            child_L=2*location;
            if(child_L!=currentSize&&myArray[child_L].compareTo(myArray[child_L+1])>0)
                child_L++;
            if(x.compareTo(myArray[child_L])>0)
                myArray[location]=myArray[child_L];
            else
                break;
        }
        myArray[location]=x;
    }

扩大数组

如果插入数据的数量大于二分之一数组的长度,则把数组扩大两倍。

    //enlarge array
    private void enLargeArray(int length){
        AnyType[] old=myArray;
        myArray= (AnyType[]) new Comparable[length];
        for (int i = 0; i < old.length; i++)
            myArray[i]=old[i];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TanGBx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值