数据结构与算法(六)

134 阅读1分钟
  • 比较器
@Override
public int compare(T o1, T o2) ;
返回负数的情况,就是o1比o2优先的情况
返回正数的情况,就是o2比o1优先的情况
返回0的情况,就是o1与o2同样优先的情况

  • 堆结构
1)堆结构就是用数组实现的完全二叉树结构
2)完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
3)完全二叉树中如果每棵子树的最小值都在顶部就是小根堆
4)堆结构的heapInsert与heapify操作

public class MaxHeap {

    static class MyMaxHeap {
        int[] arr;
        int heapSize;

        public boolean isEmpty() {
            return heapSize == 0;
        }

        public boolean isFull() {
            return heapSize == arr.length;
        }

        public MyMaxHeap(int limit) {
            this.arr = new int[limit];
            heapSize = 0;
        }

        public void push(int value) {
            if (heapSize == arr.length) {
                throw new RuntimeException("堆中已满");
            }
            arr[heapSize] = value;
            insertHeap(arr, heapSize++);

        }

        private void insertHeap(int[] arr, int index) {
            while (arr[index] > arr[(index - 1) / 2]) {
                int temp = arr[index];
                arr[index] = arr[(index - 1) / 2];
                arr[(index - 1) / 2] = temp;
                index = (index-1)/2;
            }
        }

        public int pop(){
            if(heapSize <1){
                throw new RuntimeException("堆中已空");
            }
            int value = arr[0];
            swap(arr,0,heapSize-1);

            heapify(arr,0,--heapSize);
            return value;
        }

        private void heapify(int[] arr, int index, int heapSize) {

            int left = 2*index+1;
            while (left<heapSize){
                int maxindex = ((left+1)<heapSize && arr[left+1]>arr[left]) ? left+1:left;
                if(arr[maxindex] > arr[index]){
                    swap(arr,maxindex,index);
                    left = 2*maxindex+1;
                    index = maxindex;
                }else {
                    break;
                }
            }

        }
    }
    public static class RightMaxHeap {
        private int[] arr;
        private final int limit;
        private int size;

        public RightMaxHeap(int limit) {
            arr = new int[limit];
            this.limit = limit;
            size = 0;
        }

        public boolean isEmpty() {
            return size == 0;
        }

        public boolean isFull() {
            return size == limit;
        }

        public void push(int value) {
            if (size == limit) {
                throw new RuntimeException("heap is full");
            }
            arr[size++] = value;
        }

        public int pop() {
            int maxIndex = 0;
            for (int i = 1; i < size; i++) {
                if (arr[i] > arr[maxIndex]) {
                    maxIndex = i;
                }
            }
            int ans = arr[maxIndex];
            arr[maxIndex] = arr[--size];
            return ans;
        }

    }
    public static void main(String[] args) {
        int value = 1000;
        int limit = 100;
        int testTimes = 1000000;
        for (int i = 0; i < testTimes; i++) {
            int curLimit = (int) (Math.random() * limit) + 1;
            MyMaxHeap my = new MyMaxHeap(curLimit);
            RightMaxHeap test = new RightMaxHeap(curLimit);
            int curOpTimes = (int) (Math.random() * limit);
            for (int j = 0; j < curOpTimes; j++) {
                if (my.isEmpty() != test.isEmpty()) {
                    System.out.println("Oops!");
                }
                if (my.isFull() != test.isFull()) {
                    System.out.println("Oops!");
                }
                if (my.isEmpty()) {
                    int curValue = (int) (Math.random() * value);
                    my.push(curValue);
                    test.push(curValue);
                } else if (my.isFull()) {
                    if (my.pop() != test.pop()) {
                        System.out.println("Oops!");
                    }
                } else {
                    if (Math.random() < 0.5) {
                        int curValue = (int) (Math.random() * value);
                        my.push(curValue);
                        test.push(curValue);
                    } else {
                        if (my.pop() != test.pop()) {
                            System.out.println("Oops!");
                        }
                    }
                }
            }
        }
        System.out.println("finish!");

    }
}