通过对堆结构的学习,自定一个自己的堆结构,加深对堆结构的理解。
思路
- 定义一个数组
- 定义数组的初始大小
- 定义一个堆元素个数的变量
- 返回堆顶元素。把堆元素个数-1;同时把数组最后一个数放在堆顶,然后下沉到合适的位置
- 向堆中添加数据。把新增的数据放到数组的最后一个位置,然后和自己的父亲位置的值进行对比,上浮到合适的位置。
自定义大顶堆代码
public class MyMaxHeap {
private int[] heap;
private final int limit; //初始数组的大小
private int heapSize;
public MyMaxHeap(int limit){
heap = new int[limit];
this.limit = limit;
heapSize =0;
}
public boolean isEmpty(){
return heapSize ==0;
}
public boolean isFull(){
return heapSize == limit;
}
public void push(int value){
if (heapSize == limit){
throw new RuntimeException("heap is full");
}
heap[heapSize] = value;
heapInsert(heap,heapSize++);
}
//返回堆顶元素
public int pop(){
int ans = heap[0];
swap(heap,0,--heapSize);//把最后一个位置的数据放到0位置,然后下沉
heapify(heap,0,heapSize);
return ans;
}
//从index 位置,往下看,不断的下沉
//停止的条件:较大的孩子都不再比index大了;已经没有孩子了
private void heapify(int[] arr, int index, int heapSize) {
int left = index * 2 + 1;
while (left < heapSize) { // 如果有左孩子,有没有右孩子,可能有可能没有!
// 把较大孩子的下标,给largest
int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index) {
break;
}
// index和较大孩子,要互换
swap(arr, largest, index);
index = largest;
left = index * 2 + 1;
}
}
//新进来的数,先加在index 位置,然后向上浮动
//停止条件:移动到0位置或者干不掉自己的父亲
private void heapInsert(int[] arr,int index){
while (arr[index]>arr[(index-1)/2]){
swap(arr,index,(index-1)/2);//交换自己和父亲的位置
index = (index-1)/2;//把自己的下标 换成父亲位置的下标
}
}
private void swap(int[] arr,int i,int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}