文章目录
概要
优先级队列实际是小堆,根据不同的比较方法实现小堆,也可以根据自己的需要重写比较方法,从而实现自己想要的优先级队列,获取想要的数据,接下来将会用整数模拟实现一个优先级队列;
这里我的优先是优先获取最小的元素,保证出队的永远是现存的数据里最小的;
整体架构流程
package dom.bite; import java.util.Arrays; public class PriorityQueue { public int[] elem; public int usedSize; //这里会优先插入一些元素, public PriorityQueue(int[] arr,int usedSize) { this.usedSize=usedSize; this.elem=new int[usedSize]; for (int i = 0; i < usedSize; i++) { this.elem[i]=arr[i]; } createHeap(arr); } }
- 将数据整理成小根堆,采用向下调整的方法
- http://t.csdnimg.cn/1nP5F
public void createHeap(int[] array) { int parent=(array.length-1-1)/2; while(parent>=0){ shiftDown(parent,array.length-1); parent--; } } /** * * @param root 是每棵子树的根节点的下标 * @param len 是每棵子树调整结束的结束条件 * 向下调整的时间复杂度:O(logn) */ private void shiftDown(int root,int len) { int parent=root; int end=len; int child=parent*2+1; while(child<=end){ if (child + 1 <= end && elem[child+1] > elem[child]){ child++; } if(elem[child]>elem[parent]){ swap(child,parent); parent=child; child=parent*2+1; }else{ break; } } }
再者接口就是入队元素
入队采用尾插,然后采用向上调整的方法
private void shiftUp(int child) { int parent=(child-1)/2; int end=child; child=parent*2+1; while(parent>=0){ if (child + 1 <= end && elem[child + 1]<elem[child]) { child++; } if(elem[child]<elem[parent]){ swap(child,parent); child=parent; parent=(child-1)/2; }else{ break; } } }
再者就是出队元素,优先队列出的就是最小的或者最大的看自己的选择
而后保证该队列还是小根堆或者大根堆
public void pollHeap() { if(!isEmpty()){ //不为空就进行出队操作 swap(0,usedSize-1); //交换第一个元素和最后一个元素,出队最后一个元素, 变相出队根地元素 usedSize--; //插入的元素的元素个数减一 shiftDown(0,usedSize-1); //交换上去的元素,即放在的元素向下调整 } }
获取堆顶元素
public int peekHeap() { return elem[0]; }
其他操作方法
//判断队列是否满了 public boolean isFull() { return usedSize==elem.length; } //判断队列是否为空 public boolean isEmpty() { return usedSize==0; } //交换元素 public void swap(int swap1,int swap2){ int tmp=elem[swap1]; elem[swap1]=elem[swap2]; elem[swap2]=tmp; } //满了,扩容 public void grow(){ int newCapacity=elem.length+10; elem=Arrays.copyOf(elem,newCapacity); }
小结
堆的应用 4.1 PriorityQueue的实现 用堆作为底层结构封装优先级队列 4.2 堆排序 堆排序即利用堆的思想来进行排序,总共分为两个步骤: 1. 建堆 升序:建大堆 降序:建小堆 2. 利用堆删除思想来进行排序 建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。