堆的函数主要有,插入,删除,查看堆顶元素。
建堆主要依靠插入函数。
我们需要定义一个数组,int类型长度和int类型容量。
在操作过程中我们需要用到查看父亲节点函数,查看左孩子节点函数,查看右孩子节点函数和交换元素位置函数。
除了上面之外,插入和删除两个操作需要涉及到堆的元素上浮函数和元素下沉函数。
所有信息如下所示:
代码:
package org.example.heap;
import java.util.*;
public class Heap {
private int[] heap;
private int size;
private int capacity;
public Heap(int capacity){
this.capacity = capacity;
this.size = 0;
this.heap = new int[capacity];
}
//0->1->2
public int parent(int index){
return (index - 1) / 2;
}
public int leftChild(int index){
return index * 2 + 1;
}
public int rightChild(int index){
return index * 2 + 2;
}
public void swap(int i,int j){
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
/**
* 上移
*/
public void heapUp(){
int index = size -1 ;
//一直可以移动到堆顶
while(index>0&&heap[index]>heap[parent(index)]){
swap(index,parent(index));
index = parent(index);
}
}
/**
* 下沉
*/
public void heapDown(){
int index = 0;
//有一个孩子说明就不是根节点,没必要左右节点都进行判断,因为左节点没有右节点一定没有,左节点的优先级要高于右节点
//这样子代码冗余度过高,我们考虑通过预先确定较大值的下标来简化代码
// while(leftChild(index)<size){
// int left = leftChild(index);
// int right = rightChild(index);
// if(right<size){
// int maxNum = Math.max(heap[left],heap[right]);
// if(heap[index]>maxNum)break;
// //把大的拿个换上来
// if(heap[left]<heap[right]){
// swap(index,right);
// index = rightChild(index);
// }else {
// swap(index,left);
// index = leftChild(index);
// }
// }else{
// if(heap[index]>heap[left])break;
// swap(index,left);
// index = leftChild(index);
// }
// }
while(leftChild(index)<size){
int left = leftChild(index);
int right = rightChild(index);
int min = left;
if(right<size&&heap[right]>heap[left])
min = right;
if(heap[min]<heap[index])break;
else{
swap(index,min);
index = min;
}
}
}
/**
* 插入元素
*/
public void insert(int value) {
//给堆设置一个阈值,如果堆内的元素达到了总容量的0.6自动触发扩容
size++;
if(size>=capacity*0.6){
//进行堆扩容
int[] temp = new int[capacity*2];
if (capacity >= 0) System.arraycopy(heap, 0, temp, 0, capacity);
heap = temp;
capacity*=2;
}
heap[size-1] = value;
heapUp();
}
/**
* 移除堆顶元素
*/
public void removeTop(){
if(size==0)
throw new IllegalStateException("堆是空的");
int min = heap[0];
heap[0] = heap[size-1];
size--;
heapDown();
}
/**
* 获取堆顶元素
*/
public int getTop(){
if(size>0)
return heap[0];
else
throw new IllegalStateException("堆中无元素");
}
}
我们测试一下:
package org.example.heap;
public class HeapTest {
public static void main(String[] args) {
Heap heap = new Heap(10);
heap.insert(2);
heap.insert(1);
heap.insert(3);
heap.insert(2);
heap.insert(5);
//5
System.out.println(heap.getTop());
heap.removeTop();
//3
System.out.println(heap.getTop());
heap.removeTop();
//2
System.out.println(heap.getTop());
heap.removeTop();
//2
System.out.println(heap.getTop());
heap.removeTop();
//1
System.out.println(heap.getTop());
}
}
结果符合预期