优先队列:特殊的队列,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序
堆的两个特性
结构性:用数组表示的完全二叉树
有序性:任一结点的关键字是其子树所有结点的最大值/最小值
public class MaxHeap{private int size; //当前元素个数private int capacity; //容量private int[] item;MaxHeap(int capacity){size = 0;this.capacity = capacity;item = new int[capacity + 1];item[0] = Integer.MAX_VALUE; //哨兵}public void insert(int val){if(isFull())System.out.println("插入时最大堆已满");else{int i = size + 1; //指向末尾空的地方while(val > item[i / 2]){item[i] = item[i / 2]; //把父节点换下来i = i / 2;}item[i] = val;size ++;}}public int delete(){if(isEmpty()){System.out.println("删除时最大堆为空");return -1;}else{int result = item[1]; //把最大值保存起来int temp = item[size]; //取最后一个节点size--;int parent, child;for(parent = 1; parent * 2 <= size; parent = child){child = parent * 2; //左儿子下标//右儿子存在且右儿子较大if(child != item.length && item[child] < item[child + 1]){child++; //指向右儿子}//此时child指向左右儿子中较大者if(temp > item[child])break;else //把大的换上来item[parent] = item[child];}item[parent] = temp;return result;}}public boolean isFull(){return size == capacity;}public boolean isEmpty(){return size == 0;}public static void main(String[] args) {MaxHeap maxHeap = new MaxHeap(5);maxHeap.insert(6);maxHeap.insert(3);maxHeap.insert(2);maxHeap.insert(4);maxHeap.insert(5);System.out.println(maxHeap.delete());System.out.println(maxHeap.delete());System.out.println(maxHeap.delete());System.out.println(maxHeap.delete());System.out.println(maxHeap.delete());}}
因为堆是完全二叉树,一定是平衡的,插入、删除时间复杂度与树的高度有关:
建立堆时
- 通过插入操作,将N个元素一个个相继插入到一个初始为空的堆中去,时间代价为
- 将N个元素按输入顺序存入,先满足完全二叉树的结构特性。调整各结点位置,以满足最大堆的有序特性,时间代价为
