优先级队列-堆实现

  1 package sorts;
  2
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 import java.util.Random;
  6
  7 public class PriorityQueue<T extends Comparable<T>> { // min-heap
  8     private List<T> heap = new ArrayList<>();
  9     private static final int ROOT_INDEX = 0;
 10     private static final int PRE_ROOT_INDEX = ROOT_INDEX - 1;
 11     public void offer(T obj) {
 12         heap.add(obj);//在最后增加一个元素
 13         int index = heap.size() - 1;//最后一个元素的索引
 14         while (index > ROOT_INDEX) {//在堆中加一个元素后,调整堆使其再成为一个堆
 15             index = stepUpHeap(index);//上浮
 16         }
 17     }
 18     private int stepUpHeap(int index) {
 19         int parentIndex = parent(index);//获取父节点的索引
 20         T element = heap.get(index);
 21         T parent  = heap.get(parentIndex);
 22         if (parent.compareTo(element) > 0) { //父节点大于儿子节点,交换
 23               heap.set(parentIndex, element);
 24               heap.set(index, parent);
 25               return parentIndex;  // 跳到父索引
 26          } else
 27               return ROOT_INDEX; //不需要交换
 28     }
 29     public T poll() {
 30         if (isEmpty())
 31             throw new RuntimeException();
 32         int index = heap.size() - 1;//最后一个元素的索引
 33         T least;
 34         if(index==0){
 35            least = heap.get(index);
 36            heap.remove(index);
 37         }
 38         else{
 39             T element = heap.get(index);//取最后一个元素
 40             least  = heap.get(ROOT_INDEX);//取堆的根元素
 41             heap.set(ROOT_INDEX, element);//交换这两个元素
 42             heap.set(index, least);
 43             heap.remove(index);//删除最后一个元素
 44             stepDownHeap(ROOT_INDEX);//下沉调整,使之再次成为堆
 45          }
 46          return least;
 47     }
 48     private void stepDownHeap(int index) {
 49         int p = index;//parent
 50         int lchild = lchild(p);//左子节点
 51         T temp = heap.get(p);
 52         while(lchild<heap.size()){
 53         if(lchild+1<heap.size() && heap.get(lchild+1).compareTo(heap.get(lchild))<0)//右节点比左节点小
 54             lchild = lchild + 1;//取两个儿子节点中小的一个
 55             if(temp.compareTo(heap.get(lchild))<=0)//不需要调整了
 56                     break;
 57             else {
 58                  heap.set(p,heap.get(lchild));//较小的儿子节点上浮
 59                  p = lchild;
 60                  lchild = lchild(p);//继续调整
 61             }
 62         }
 63         heap.set(p,temp);//最后要将temp放到p
 64     }
 65     public T peek() {
 66         if (isEmpty())
 67             throw new RuntimeException();
 68         return heap.get(0);
 69     }
 70     public boolean isEmpty() {
 71         return heap.isEmpty();
 72     }
 73     public int size() {
 74         return heap.size();
 75     }
 76     @Override
 77     public String toString() {
 78         return heap.toString();
 79     }
 80     // index starts from 0
 81     private int parent(int index) {
 82         if (index%2==0) {
 83             return ( index / 2 ) - 1;
 84         } else {
 85             return index / 2;
 86         }
 87     }
 88     private int lchild(int index) {
 89         return index * 2 + 1;
 90     }
 91     private int rchild(int index) {
 92         return index * 2 + 2;
 93     }
 94     // test
 95     public static void main(String[] args) {
 96         Random random = new Random();
 97         PriorityQueue<Integer> pq = new PriorityQueue<>();
 98         for (int i = 0; i < 10; i++) {
 99             pq.offer(random.nextInt(100));
100         }
101         for (int i = 0; i < 10; i++) {
102             System.out.print(pq.poll() + " ");
103         }
104     }
105 }
时间: 2024-10-23 22:43:38

优先级队列-堆实现的相关文章

优先级队列-堆

1 #include <cstdio> 2 #include <iostream> 3 4 using namespace std; 5 6 const int MAX_N = 1000; 7 8 // 用数组来实现二叉树 9 // 左儿子编号=自己*2 + 1 10 // 右儿子编号=自己*2 + 1 11 int heap[MAX_N],sz=0; 12 13 // 实现最小堆 14 void push(int x) 15 { 16 // 取最后一个节点的编号,并递增. 17

初学算法-基于最小堆的优先级队列C++实现

笔者近日实现了最小堆类及其派生的优先级队列,特将代码奉上,不足之处还请指出! 在实现优先级队列时,笔者表示萌萌哒没有用过template写派生类,结果写完了出现error: *** was not decleared in this scope..后来各种补上this->才完事,在CSDN(笔者的帖子地址? http://bbs.csdn.net/topics/391806995)上提问后才知道是模板参数依赖,笔者表示涨姿势了.. /**  * The Minimum Heap Class an

python[数据]--队列,堆,优先级队列

队列:from collections import deque:实现保存最后几条历史记录,list = deque(maxlen=6),那么超过六条记录会删除之前的记录. 堆:import heapq;最大特点是第一弹出的元素总是堆中最小的元素:list=[1,2,3] heap=heapq.heapify(list) ,nlargest(3,数据,key=lambda) nsmallest() 优先级队列:堆中的元素(-优先级,序号,item)这样即可实现优先级,优先级越高最先pop出堆,优

基于堆的最大最小优先级队列的实现

最大堆能够在O(1)的时间内取得集合中的最大值,并且在集合中加入新元素的时候,能够以O(Logn)的时间将新的元素插入到堆中. 当取出最大的元素时,能够以O(Logn)的时间重新将堆整理成最大堆.最小堆同理. 最大优先级队列的应用实例:基于优先级的作业调度,在所有等待调度的作业中,选择具有最大优先级作业进行处理.同时一个新的作业也可以插入到队列里面去. 例如可以实现自己的基于优先级的多线程作业调度程序. 最小优先级队列的应用实例:可以实现一个基于时间的作业调度程序,时间最小的被优先选择进行事件通

STL源码笔记(15)—堆和优先级队列(二)

STL源码笔记(15)-堆和优先级队列 优先级队列的源码实现基于heap的操作,底层容器默认是vector. 优先级队列简介 优先级队列跟队列类似,一端插入一端删除,不同的是,优先级队列的元素入队后会根据其优先级进行调整,默认情况下优先级高的将优先出队,在SGI STL中,优先级队列的功能保证由heap实现:stl_heap.h中,heap的分析见:STL堆源码分析 优先级队列构造函数 默认情况下,优先级队列使用vector作为底层容器,使用less作为比较函数,其在源码中的定义声明如下: te

STL源码笔记(14)—堆和优先级队列(一)

STL源码笔记(14)-堆和优先级队列 priority_queue是拥有权值观念的queue,跟queue类似,其只能在一端push,一端pop,不同的是,每次push元素之后再容器内部元素将按照一定次序排列,使得pop得到的元素始终是当前权值的极大值. 很显然,满足这个条件就需要某些机制了,缺省情况下使用max-heap大顶堆来实现,联想堆排序的实现,使用大顶完成序列从小到大的排序,过程大概是: 把堆的根元素(堆中极大值)交换到最后 堆的长度减1 这样每次取出堆中的极大值完成排序,刚好与优先

【数据结构】用模版实现大小堆、实现优先级队列,以及堆排序

一.用模版实现大小堆 如果不用模版的话,写大小堆,就需要分别实现两次,但是应用模版的话问题就简单多了,我们只需要实现两个仿函数,Greater和Less就行了,仿函数就是用类实现一个()的重载就实现了仿函数.这个看下代码就能理解了.再设计参数的时候,需要把模版设计成模版的模版参数,因为要实现大小堆嘛!当我们实现好一个大堆或者小队的逻辑后只需要用模版接收的Greater或Less类定义一个变量,就能实现通用功能了. template<typename T> struct Less {     b

优先级队列及小顶堆排序

优先级队列及小顶堆排序实现 /** @file          HeapSort.h *  @copyright     personal *  @brief         优先级队列及堆排序 *  @version       V1.0.0 *  @author        fangyuan *  @date          2015/12/31 *  @note          测试版本 */ #include "iostream" using namespace std

JAVA优先级队列测试

package code.test; import java.util.Comparator; import java.util.Iterator; import java.util.PriorityQueue; import java.util.Queue; /** * 实验表明,在java中: * 1.优先级队列打印或者迭代,得到的输出顺序为堆结构数组的顺序,大致有序但不完全保证顺序 * 2.由于堆排序是不稳定排序,在优先级相同的情况下,元素不会保持原来的顺序输出 * Created by