优先级队列实现

优先级队列的底层实现是堆(最大堆、最小堆)

一、堆的特点

  1. 完全二叉树
  2. 每个节点的值都必须大于等于或小于等于子树中节点的值(对应最大堆、最小堆)
  3. 往堆中插入和删除一个元素的时间复杂度都是O(logn)

二、实现

最大堆和最小堆实现原理基本一样,下面实现一个最大堆

package main

type MaxHeap struct {
   array []int //数组,从下标1开始存储数据
   count int   //堆中已经存储的数据个数
   size  int
}

//初始化一个堆
func NewMaxHeap(size int) *MaxHeap {
   obj := &MaxHeap{
      size:  size,
      count: 0,
      array: make([]int, size),
   }
   return obj
}

//往堆中添加一个元素
func (this *MaxHeap) Push(data int) bool {
   if this.count >= this.size {
      return false
   }
   this.array[this.count] = data
   i := this.count
   this.dowToUp(i)
   this.count++
   return true
}

//移除堆顶元素
func (this *MaxHeap) Pop() int {
   if this.count == 0 {
      return -1 //堆中没有数据
   }
   max := this.array[0]
   this.array[0] = this.array[this.count-1] //将最后一个元素放到堆顶
   this.count--
   this.upToDown(0) //堆化
   return max
}

//获取当前存储元素的个数
func (this *MaxHeap) Count() int {
   return this.count
}

//从下往上堆化
func (this *MaxHeap) dowToUp(i int) {
   for (i-1)/2 >= 0 && this.array[i] > this.array[(i-1)/2] {
      this.swap(i, (i-1)/2)
      i = (i - 1) / 2
   }
}

//自上往上堆化
func (this *MaxHeap) upToDown(i int) {
   for {
      a := this.array
      n := this.count
      maxPos := i

      leftNode := i*2 + 1
      rightNode := i*2 + 2

      if leftNode < n && a[i] < a[leftNode] {
         maxPos = leftNode
      }
      if rightNode < n && a[maxPos] < a[rightNode] {
         maxPos = rightNode
      }
      if maxPos == i {
         break
      }
      this.swap(i, maxPos)

      i = maxPos //再检测子节点
   }
}

func (this *MaxHeap) swap(i int, j int) {
   this.array[i], this.array[j] = this.array[j], this.array[i]
}

这个最大堆本质就是一个优先级从高到低的队列,下面是测试

func main() {
   //待入队元素
   a := []int{8, 7, 6, 9, 0, 5, 1, 2, 3, 4}

   //new一个优先级队列
   priorityQueue := NewMaxHeap(len(a))
   for i := 0; i < len(a); i++ {
      priorityQueue.Push(a[i]) //依次入队
   }

   //依次出队
   for priorityQueue.Count() > 0 {
      fmt.Print(priorityQueue.Pop(), " ")
   }
}

输出

9 8 7 6 5 4 3 2 1 0 

三、堆排序

1.每次将堆中最大的元素移到数组的末尾
2.剩下n-1个元素重新堆化
3.重复到此过程至下标1的元素


func NewMaxHeadByArray(a []int) *MaxHeap {
 n := len(a)
 obj := &MaxHeap{
  array: a,
  count: n,
  size: n,
 }
 //堆化
 for i := n / 2; i >= 0; i-- {
  obj.upToDown(i)
 }
 return obj
}

//堆排序
func MaxHeapSort(a []int) {
 heap := NewMaxHeadByArray(a)
 for heap.count > 0 {
  //将最大的元素移到数组最后
  heap.array[0], heap.array[heap.count-1] = heap.array[heap.count-1], heap.array[0]
  //减少堆的长度
  heap.count--
  //堆顶元素改变,重新堆化,保持堆的特性
  heap.upToDown(0)
 }
}

测试

func main() {
 //待入队元素
 a := []int{8, 7, 6, 9, 0, 5, 1, 2, 3, 4}
 MaxHeapSort(a)
 fmt.Println(a)
}

输出

[0 1 2 3 4 5 6 7 8 9]

堆排序的复杂度为O(nLogn)

原文地址:https://www.cnblogs.com/chenqionghe/p/12161365.html

时间: 2024-11-02 17:12:47

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

Rabbitmq中的优先级队列操作

1.%% 普通队列操作 in(X, 0, {queue, [_] = In, [], 1}) ->{queue, [X], In, 2}; in(X, 0, {queue, In, Out, Len}) when is_list(In), is_list(Out) -> {queue, [X|In], Out, Len + 1}; 优先级队列操作: in(X, Priority, Q = {queue, [], [], 0}) -> in(X, Priority, {pqueue, []

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

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

【转】java中PriorityQueue优先级队列使用方法

优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,字符串则按字典序排列. 由于网上的资料大多将优先级队列各个方法属性,很少有实例讲解的,为方便大家以后使用,我就写了个demo~ 如果想实现按照自己的意愿进行优先级排列的队列的话,需要实现Comparator接口.下面的方法,实现了根据某个变

STL学习系列七:优先级队列priority_queue容器

1.简介 最大值优先级队列.最小值优先级队列 优先级队列适配器 STL priority_queue 用来开发一些特殊的应用,请对stl的类库,多做扩展性学习 如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了.这样,我们就引入了优先级队列 这种数据结构. 优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一

优先级队列及小顶堆排序

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

初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现

这一次,笔者使用了STL库中的优先级队列(Priority Queue)来完成Dijkstra算法中extract-min()语句(即从未选中的节点中选取一个距离原点s最小的点)的功能.由于优先级队列的插入.删除操作只需要logn的时间花费,因此降低了不少运行时间. 本文使用C++实现了这一基本算法.参考<算法导论>第24.3节. /**  * Dijkstra's Single Source Shortest Path Algorithm in C++  * Time Cost : O(Ml

STL之优先级队列priority_queue

摘要: priority_queue,自适应容器(即容器适配器):不能由list来组建: 最大值优先级队列(最大值始终在对首,push进去时候) 最小值优先级队列: 优先级队列适配器 STL  priority_queue priority_queue<int, deque<int> > pg; priority_queue<int, vector<int> > pg; STL中实现的方法: pg.empty(); pg.size(); pg.top();

队列的应用:优先级队列

优先级队列:如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了. 优先级队列(priority queue)是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一个新元素(3)删除 一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 .对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行. 以上是网上常见的对优先级队列的描述.偷

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

优先级队列与堆排序

转自:http://www.cnblogs.com/yangecnu/p/Introduce-Priority-Queue-And-Heap-Sort.html 在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象.最简单的一个例子就是,在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话. 在这种情况下,我们的数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象.这种数据结构就是优先级队列(Pri