数据结构--优先队列(堆排序)
优先队列:不是先进先出啦,下面的代码是大顶堆,大的先出。
在之前理解堆排序的基础上,在来理解优先队列。
还是用这个公式:
leftNo = parentNo*2+1
rightNo = parentNo*2+2
parentNo = (nodeNo-1)/2
每次进队列是从最后进,在慢慢上浮。
每次出队列,堆顶先出,在把队尾调到堆顶,在下浮。
上代码
package sy181002; import java.util.Arrays; /** * 优先队列 * */ public class PriorityQueue { private int[] array; //size是指向下一次插入的位置,就是元素个数 private int size; public PriorityQueue() { array=new int[32]; } /** * 入队 从最后插入 所以上浮 * @param key 入队元素 */ public void enQueue(int key) { //队列长度超出范围,扩容 if(size>=array.length) resize(); array[size++]=key; upAdjust(); } /** * 出队 第一个删除,把最后一个元素顶替到第一个 */ public int deQueue() throws Exception { if(size<=0) throw new Exception("队列空了"); //获取堆顶元素 int head=array[0]; //最后一个元素移动到堆顶 array[0]=array[--size]; downAdjust(); return head; } /** * 上浮调整 * 从最后插入元素,所以其要一直上浮到比其父节点小为止 * c=2p+1 */ public void upAdjust() { int child=size-1; int parent=child-1; int temp=array[child]; while(child>0 && temp>array[parent]) { array[child]=array[parent]; child=parent; parent=(child-1)/2; } array[child]=temp; } /** * 下沉调整 * 最大值出队列,让最后一个值到队首,一直调整下去 * 保证左右孩子中右节点最大 * 当父节点比孩子节点小时,父节点交换 */ public void downAdjust () { int parent=0; int child=1; int temp=array[parent]; while(child<size) { if(child+1<size && array[child+1]>array[child]) { child++; } if(temp>=array[child]) break; array[parent]=array[child]; parent=child; child=(2*child)+1; } array[parent]=temp; } public void resize() { int newSize=this.size*2; this.array=Arrays.copyOf(this.array, newSize); } public void show() { for (int i : array) { System.out.print(i+" "); } } }
测试类
package sy181002; public class PriheapTest { public static void main(String[] args) throws Exception { PriorityQueue priorityQueue = new PriorityQueue(); priorityQueue.enQueue(3); priorityQueue.enQueue(7); priorityQueue.enQueue(3); priorityQueue.enQueue(1); priorityQueue.enQueue(44); priorityQueue.enQueue(41); priorityQueue.show(); System.out.println(); System.out.println("出队"+priorityQueue.deQueue()); priorityQueue.show(); System.out.println(); System.out.println("出队"+priorityQueue.deQueue()); priorityQueue.show(); System.out.println(); System.out.println("出队"+priorityQueue.deQueue()); priorityQueue.show(); System.out.println(); System.out.println("出队"+priorityQueue.deQueue()); priorityQueue.show(); System.out.println(); System.out.println("出队"+priorityQueue.deQueue()); priorityQueue.show(); System.out.println(); } }