码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-09-09 23:09:24      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:父节点   16px   ping   str   i++   radius   splay   art   ott   

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

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

用堆实现优先队列:

技术分享图片

  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 

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

标签:父节点   16px   ping   str   i++   radius   splay   art   ott   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!