自定义一个堆结构

3,833 阅读2分钟

通过对堆结构的学习,自定一个自己的堆结构,加深对堆结构的理解。

思路

  1. 定义一个数组
  2. 定义数组的初始大小
  3. 定义一个堆元素个数的变量
  4. 返回堆顶元素。把堆元素个数-1;同时把数组最后一个数放在堆顶,然后下沉到合适的位置
  5. 向堆中添加数据。把新增的数据放到数组的最后一个位置,然后和自己的父亲位置的值进行对比,上浮到合适的位置。

自定义大顶堆代码

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;
    }