题外话
把没写的都补回来!
正题
堆
概念
堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储,
大根堆:指根结点比左右孩子都大的堆
小根堆:指根结点比左右孩子都小的堆
性质
1.堆中某个节点的值总是不大于或不小于其父节点的值
2.堆总是一棵完全二叉树。
向上调整
将数组调整为大根堆:
1.从最后一颗子树开始调整,利用二叉树的性质找到最后一颗树的父亲节点 (i-1)/2
2.获取左右孩子的最大值和根节点比较,如果比根节点大就交换,并且继续向下调整
3.调整完结点之后,让结点下标减1,即可从下往上调整为大根堆,一直调整到0下标

底层代码实现及详解
public class HeapBottom {
//创建数组private int[] elem;
//计数数组元素个数public int usedSize;public HeapBottom(){this.elem=new int[10];}//初始化elem数组public void intElem(int[] array){for (int i = 0; i < array.length; i++) {elem[i]=array[i];usedSize++;}}//创建大根堆public void createHeap(){for (int parent = (elem.length-1)/2; parent>=0 ; parent--) {
//向上调整siftDown(parent,usedSize);}}//向上调整private void siftDown(int parent,int len){
//创建child为parent左子树int child=parent*2+1;
//child小于数组长度时while (child<len){
//如果child+1也小于数组长度,并且左子树小于右子树if (child+1<len&&elem[child]<elem[child+1]){
//将右子树下标赋给左子树,此时child相当于右子树child=child+1;}
//如果右子树大于父亲结点if (elem[child]>elem[parent]){
//交换元素值
swap(parent,child);
//并继续向下调整(因为刚交换完的结点不一定是交换后的最大值),将交换完的子树下标给到parentparent=child;
//让child为parent左孩子child=parent*2+1;}
//如果右子树不大于父亲节点,则退出else {break;}}}
//交换代码
private void swap(int i,int j)
{
int temp=elem[i];
elem[i]=elem[j];
elem[j]=temp;
}
}
//添加元素
public void push(int val)
{//判断是否满了,满了扩容if (isFull()){Arrays.copyOf(elem,elem.length*2);}//赋值给最后一个元素elem[usedSize]=val;//向上调整siftUp(usedSize);usedSize++;
}
public boolean isFull()
{return usedSize==elem.length;
}
//向上调整
public void siftUp(int child)
{int parent=(child-1)/2;while (child>0) {if (elem[child] > elem[parent]) {swap(child, parent);child = parent;parent = (child - 1) / 2;}else {break;}}}
//删除元素(数组0下标位置元素和最后一个元素互换位置,然后向上调整即可)public int pop(){
//判断是否为空数组,空了返回-1(自定义异常也可以)if (empty()){return -1;}
//将删除元素记录下来int tmp=elem[0];
//互换位置swap(0,usedSize-1);
//数组元素数量-1usedSize--;
//向上调整siftDown(0,usedSize);return tmp;}
//判断是否为空public boolean empty(){return usedSize==0;}
}
小结
今天还没吃饭,先去吃饭休息休息!!