优先级队列实现
时间:2020-01-07
本文章向大家介绍优先级队列实现,主要包括优先级队列实现使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
优先级队列的底层实现是堆(最大堆、最小堆)
一、堆的特点
- 完全二叉树
- 每个节点的值都必须大于等于或小于等于子树中节点的值(对应最大堆、最小堆)
- 往堆中插入和删除一个元素的时间复杂度都是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
- UDF编程操作实现
- GitHub敏感信息扫描工具
- Java数据结构和算法(九)——高级排序
- Java数据结构和算法(十一)——红黑树
- Entity Framework Core 之数据库迁移
- 常见Web源码泄露总结
- 浅析Entity Framework Core2.0的日志记录与动态查询条件
- ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截)
- 【weakfilescan】敏感文件扫描工具
- ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)
- ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器)
- CVE-2017-11882漏洞复现
- ASP.NET Core使用静态文件、目录游览与MIME类型管理
- Python 黑客——使用Python破解门禁系统
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android使用AsyncQueryHandler实现获取手机联系人功能
- Android用过TextView实现跑马灯效果的示例
- android如何设置Activity背景色为透明色
- Android 手机防止休眠的两种实现方法
- Android编程实现的首页左右滑动切换功能示例
- 零基础学小程序004----小程序post请求,提交数据到服务器,小程序下单,小程序用户注册功能
- HorizontalScrollView水平滚动控件使用方法详解
- Android Activity生命周期和堆栈管理的详解
- Android学习之SharedPerference存储详解
- Android编程实现对话框Dialog背景透明功能示例
- Android开发中DatePicker日期与时间控件实例代码
- Android Shader应用开发之霓虹闪烁文字效果
- Android中ToggleButton开关状态按钮控件使用方法详解
- 零基础学小程序005---小程序登陆注册功能实现
- Android RecyclerView 复用错乱通用解法详解