【转】用大顶堆实现优先队列

队列的特点是先进先出。通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西。但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出。这就很像堆的特征:总是移除优先级最高的根节点。

重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限。不分排队的顺序!

用堆实现优先队列:


  1. //最大堆
  2. import java.util.ArrayList;
  3. public class Heap<E extends Comparable>{
  4. private ArrayList<E> list=new ArrayList<E>();//用数组实现堆
  5. public Heap(){}
  6. public Heap(E[] objects){
  7. for(int i=0;i<objects.length;i++){
  8. add(objects[i]);
  9. }
  10. }
  11. public void add(E newObject){//添加一个元素
  12. list.add(newObject);
  13. int currentIndex=list.size()-1;
  14. while(currentIndex>0){
  15. int parentIndex=(currentIndex-1)/2;//找到该结点的父结点
  16. if(list.get(currentIndex).compareTo(list.get(parentIndex))>0){//与父节点比较
  17. //如果当前结点的值大于父结点就交换位置
  18. E temp=list.get(currentIndex);
  19. list.set(currentIndex, list.get(parentIndex));
  20. list.set(parentIndex, temp);
  21. }
  22. else
  23. break;
  24. currentIndex=parentIndex;
  25. }
  26. }
  27. public E remove(){//删除并返回根结点,堆的特点是移除了根结点后还是堆
  28. if(list.size()==0) return null;
  29. E removeObject=list.get(0);
  30. list.set(0, list.get(list.size()-1));//把最后一个结点放在根结点的位置
  31. list.remove(list.size()-1);
  32. int currentIndex=0;
  33. while(currentIndex<list.size()){
  34. int leftChildIndex=2*currentIndex+1;
  35. int rightChildIndex=2*currentIndex+2;//左右孩子结点的坐标
  36. if(leftChildIndex>=list.size())break;
  37. //比较左右孩子的值,使maxIndex指向值大的结点
  38. int maxIndex=leftChildIndex;
  39. if(rightChildIndex<list.size()){
  40. if(list.get(maxIndex).compareTo(list.get(rightChildIndex))<0){
  41. maxIndex=rightChildIndex;
  42. }
  43. }
  44. //如果当前结点的值小于其左右孩子中的大的值,就交换两个结点
  45. if(list.get(currentIndex).compareTo(list.get(maxIndex))<0){
  46. E temp=list.get(maxIndex);
  47. list.set(maxIndex, list.get(currentIndex));
  48. list.set(currentIndex, temp);
  49. currentIndex=maxIndex;
  50. }
  51. else
  52. break;
  53. }
  54. return removeObject;
  55. }
  56. public int getSize(){
  57. return list.size();
  58. }
  59. }

MyPriorityQueue.java


  1. public class MyPriorityQueue<E extends Comparable> {
  2. private Heap<E> heap=new Heap<E>();//用堆实现优先队列
  3. //入队列
  4. public void enqueue(E e){
  5. heap.add(e); //这个add以后,堆会自己调整成一个新堆
  6. }
  7. //出队列
  8. public E dequeue(){
  9. return heap.remove();//这移除出之后,堆会自己调整,还是一个新堆
  10. }
  11. public int getSize(){
  12. return heap.getSize();
  13. }
  14. }

TestMyPriorityQueueMainClass.java


  1. public class TestMyPriorityQueueMainClass {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. Patient p1=new Patient("John",2);
  5. Patient p2=new Patient("Tom",9);
  6. Patient p3=new Patient("Jack",4);
  7. Patient p4=new Patient("Michael",6);
  8. MyPriorityQueue<Patient> priorityQueue=new MyPriorityQueue<>();
  9. priorityQueue.enqueue(p1);
  10. priorityQueue.enqueue(p2);
  11. priorityQueue.enqueue(p3);
  12. priorityQueue.enqueue(p4);
  13. while(priorityQueue.getSize()>0){
  14. System.out.print(priorityQueue.dequeue()+" ");
  15. }
  16. }
  17. static class Patient implements Comparable{
  18. private String name;
  19. private int priority;
  20. public Patient(String name,int priority){
  21. this.name=name;
  22. this.priority=priority;
  23. }
  24. public String toString(){
  25. return name+"(priority:"+priority+")";
  26. }
  27. @Override
  28. public int compareTo(Object oo) {//比较优先级
  29. // TODO Auto-generated method stub
  30. return this.priority-((Patient)oo).priority;
  31. }
  32. }
  33. }

测试结果:优先级高的先输出,优先级最高的就是堆的根节点

原文地址:https://blog.csdn.net/tuke_tuke/article/details/50358606

原文地址:https://www.cnblogs.com/hirampeng/p/9615658.html

时间: 2024-10-04 05:45:35

【转】用大顶堆实现优先队列的相关文章

Leetcode 155 Min Stack 小顶堆+栈,优先队列实现 难度:0

https://leetcode.com/problems/min-stack/ #include <vector> #include <queue> #include <map> #include <iostream> using namespace std; class MinStack { public: vector<int> vec; priority_queue<int,vector<int>,greater<

python 大顶堆 小顶堆

http://www.coder4.com/archives/3844 需1求:给出N长的序列,求出TopK大的元素,使用小顶堆,heapq模块实现. import heapq import random class TopkHeap(object): def __init__(self, k): self.k = k self.data = [] def Push(self, elem): if len(self.data) < self.k: heapq.heappush(self.data

[ACM] POJ 1442 Black Box (堆,优先队列)

Black Box Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7099   Accepted: 2888 Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empt

POJ3253 Fence Repair 小顶堆+贪心

给了你N个木棒,求把他们组装成一根需要的最小花费,每次只能选两根组装在一起,需要的花费为两个木棒之和, 以前遇到过把一整根切开的,那个是DP,这个则有些类似,可是大胆的猜测了一下,直接每次选取所有木棒中最短的两根,这样就可以了,那么贪心是适用的,但是数量很多,而且两根最短的组装好了得插回去,这样不可能每次都排序吧, 这题首先优先队列肯定是可以做的, 最小堆也是可以的,每次都选出堆里的最小的两个求和再放回去即可 队列本身也就是堆吧,所以差别不大,但是没用过最小堆最大堆的 所以用一次把 #inclu

算法系列(十)堆实现优先队列

在算法系列(九)平衡二叉查找树AVL树中介绍了AVL树.这篇文章主要讲解优先队列. 一般都使用二叉堆来实现优先队列.暂时之说这种实现. 堆的定义和性质 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2] 即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字. 堆分为大顶堆和小顶堆,满足Key[i]

最小堆(优先队列)基本概念,即一个完整建立,插入,删除代码

堆(优先队列)priority queue特殊的队列,取出元素的顺序是依照元素的优先权(关键字)大小,而出元素进入队列的先后顺序操作:查找最大值(最小值),删除(最大值) 数组:链表:有序数组:有序链表: 采用二叉搜索树? NO 采用完全二叉树 YES堆的连个特性结构性:用数组表示的完全二叉树:有序性:任一结点的关键字是其字树所有结点的最大值(或最小值) 最大堆(MaxHeap)也称大顶堆:最大值 最小堆(MinHeap)也称"小顶堆":最小值 从根节点到任意结点路径上结点序列的有序性

0038数据结构之堆和优先队列

优先队列:出队顺序和入队顺序无关,而是和优先级有关(优先级高的先出队) 如果使用普通线性结构或者顺序线性结构实现优先队列,出队或者入队总有一方是O(n)级别的:如果使用堆实现优先队列,能使入队和出队的时间复杂度都是O(logn),效率是极高的. 二叉堆是一颗完全二叉树,不一定是满二叉树,但是确实节点的那部分一定是在整棵树的右下侧.满足的规律:1)根节点最大, 2)确实节点的那部分在整棵树的右下侧.(低层次的节点不一定大于高层次的节点) 下图是一颗最大堆: 可以用数组存储: 从数组1位置开始存储:

堆与优先队列

当我们需要高效的完成以下操作时: 1.插入一个元素 2.取得最小(最大)的数值,并且删除 能够完成这种操作的数据结构叫做优先队列 而能够使用二叉树,完成这种操作的数据结构叫做堆(二叉堆) 堆与优先队列的时间复杂度: 若共有n个元素,则可在O(logn)的时间内完成上述两种操作 堆的结构如下图: 堆最重要的性质就是儿子的值一定不小于父亲的值,且堆从上到下,从左到右紧密排列. 堆的操作: 当我们希望向堆中插入元素时,堆的内部会进行如下操作(以插入元素3为例): (1.在堆的末尾插入该值) (2.不断

堆和优先队列

1 二叉堆和优先队列的概念 1.1 二叉堆 二叉堆堆是一个数组,它可以被看成一个近似的完全二叉树,树上每一个结点对应数组中的一个元素.除了最底层外,该树是完全充满的,而且是从左到右填充.表示堆的数组A包括两个属性:A.length给出数组元素的个数,A.heap_size表示有多少个堆元素存储在该数组中,这里,0<=A.heap_size<=A.length. 如下图所示: 堆可以分成两种:最大堆和最小堆.在最大堆中,任何节点的值都大于等于其孩子的值,故根节点是数组中的最大数所在节点.反之,最