赞
踩
如果有一个集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
使用代码来实现一个大根堆。
接口成员方法。
public class PriorityQueue { public int[] elem; public int usedSize; public PriorityQueue() {} //建堆 public void createHeap(int[] array) {} /** * @param root 是每棵子树的根节点的下标 * @param len 是每棵子树调整结束的结束条件 * 向下调整的时间复杂度:O(logn) */ private void shiftDown(int root,int len) {} // 入堆:仍然要保持是大根堆 public void push(int val) {} private void shiftUp(int child) {} //判断堆是否满 public boolean isFull() {} //每次删除的都是优先级高的元素,删除后任是大根堆 public void pollHeap() {} //判断堆是否为空 public boolean isEmpty() {} // 获取堆顶元素 public int peekHeap() {} }
在构造方法中构建为长度10的数组。
public PriorityQueue() {
elem = new int[10];
}
createHeap思路:
shiftDown思路:
public void createHeap(int[] array) { if(elem.length < array.length){ elem = Arrays.copyOf(elem, elem.length * 2); } for (int i = 0; i < array.length; i++){ elem[i] = array[i]; usedSize++; } for (int root = (usedSize -1 -1) / 2; root >= 0 ; root--) { shiftDown(root,usedSize); } } /** * @param root 是每棵子树的根节点的下标 * @param len 是每棵子树调整结束的结束条件 * 向下调整的时间复杂度:O(logn) */ private void shiftDown(int root,int len) { int child = root * 2 + 1; while (child < len){ //寻找孩子节点的大值 if(child + 1 < len && elem[child] < elem[child + 1]){ child++; } if(elem[root] < elem[child]){ swap(elem,root,child); root = child; child = root * 2 + 1; }else { break; } } } //交换函数 private void swap(int[] array,int x,int y){ int tmp = array[x]; array[x] = array[y]; array[y] = tmp; }
代码思路:
/** * 入堆:仍然要保持是大根堆 * @param val */ public void push(int val) { if(isFull()){ elem = Arrays.copyOf(elem, elem.length*2); } elem[usedSize] = val; shiftUp(usedSize); usedSize++; } private void shiftUp(int child) { int parent = (child - 1) / 2; while(parent >= 0) { if (elem[parent] < elem[child]) { swap(elem, parent, child); child = parent; parent = (child - 1) / 2; }else { break; } } }
这个方法直接使用成员变量usedSize和数组长度判断即可。
public boolean isFull() {
return usedSize == elem.length;
}
代码思路:
ublic void pollHeap() throws NullPointerException {
if (isEmpty()) {
throw new NullPointerException();
}
swap(elem,0,usedSize-1);
shiftDown(0,usedSize);
usedSize--;
}
这个方法直接使用成员变量usedSize是否为0就行。
public boolean isEmpty() {
return usedSize == 0;
}
如果堆为空,抛空指针异常,没有直接返回堆顶元素。
public int peekHeap() throws NullPointerException {
if (isEmpty()) {
throw new NullPointerException();
}
return elem[0];
}
在Java中使用集合类PriorityQueue来表示优先级队列,其底层是一个小根堆。
提供了以下3种构造方法:
方法 | 方法用途介绍 |
---|---|
PriorityQueue() | 创建一个空的优先级队列,默认容量是11 |
PriorityQueue(int initialCapacity) | 创建一个初始容量为initialCapacity的优先级队列,注意initialCapacity不能小于1,否则会抛IllegalArgumentException异常 |
PriorityQueue(Collection<? extends E> c) | 用一个集合来创建优先级队列 |
常用方法如下:
import java.util.PriorityQueue;
ClassCastException
异常。NullPointerException
。Comparator
后重写 compare
方法时将比较改为public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。