博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
倍道而行 :堆(heap)
阅读量:4498 次
发布时间:2019-06-08

本文共 1209 字,大约阅读时间需要 4 分钟。

 

概念


 先来两个概念(别头疼):

普通队列:先进先出,后进后出

优先队列出队顺序和入队顺序无关;和优先级相关。就好比:我们的电脑操作系统会按照各个进程的优先级来安排CPU执行哪一个进程。

堆(heap)被称为一种优先队列,但是堆的本质不是队列。取出顺序就是每次取最大的呗。

下图就是一个堆:

本质就是一个完全二叉树。完全二叉树的定义看图就可得出:父节点都大于等于子节点。且是从上大下,从左至右的排序。

 

堆的实现


看图:

仔细看每个数的下标。数组是从1开始的。父节点和子节点的关系也可以很容易得出。

eg:41是28和16的父节点,下标分别为2、4、5,满足图中的公式。

如题:有10个数,请用代码将之组成一个堆?

算法思想:每次往里面插入一个数,我们只需要比较插入的数和其父节点数的大小就行。

代码:

k指的是插入的序号。建议大家这样理解: 假设现在已经构建好了有10个数的堆,我再往里面插入一个数为102,即第11个数。那么k=11.然后与其父节点(k/2=5),即arr[5]进行比较。若大于父节点就交换位置,并让k/2=2,继续进行下去,至到和根结点进行比较。 void shiftUp(int k,int arr[]){    while (k>1 && arr[k/2]

 取堆里面的数:每次取都是取第一个位置的数,也就是最大的数。


 如题:现在构建好了一个堆,那么我取走第一个数后,整个堆就需要进行调整,那该如何?

目前思想:(以本遍博客上面的例子为例,读者可以对照着看) 

本题的:k代表开始的位置为1,j为子节点的位置(eg:指的是62这个根的左右两个子节点)

  • 1.取走62,我就让15代替62的位置。即,用最末尾的数字放到根节点上。
  • 2.比较用15和62的两个左右节点进行比较,如果大就不做处理,否则交换位置并且,让k=j.
  • 继续走第二步
void shiftDown(int k,int arr[],int count ){    while (2*k< count) { //确认有左子节点        int j = 2*k;        if (j+1
arr[j]) { //如果有右节点 j+=1; } if (arr[k]>arr[j]) { 如果,比较发现字节点没有父节点大,就退出 break; } swap(arr[k], arr[j]);//否则就交换位置 k = j;//然后让k=j,继续进行比较。 }}

 

结尾:     


 堆排序算法还是很简单的。

建立堆,然后一个一个的取出,那么这就是一个从大到小的一个有序的序列。

 

转载于:https://www.cnblogs.com/yuhui-snail/p/8581107.html

你可能感兴趣的文章
David Silver强化学习Lecture1:强化学习简介
查看>>
开源项目
查看>>
unix系统内核优点
查看>>
协议(五)-从电报机到智能手机
查看>>
蓝瘦香菇
查看>>
Python学习-5.Python的变量与数据类型及字符串的分割与连接
查看>>
98%的人没解出的德国面试逻辑题
查看>>
mysql 复制表结构 / 从结果中导入数据到新表
查看>>
fiddler---使用方法2--抓取其他电脑数据包
查看>>
python基础教程——切片
查看>>
android 获取坐标【转】
查看>>
Windows Text Copyer 1.1绿色版
查看>>
内存重叠strcpy\memcpy
查看>>
球的移动(move)
查看>>
页面禁止双击选中
查看>>
打印流
查看>>
TCP/IP模型的一个简单解释
查看>>
解开最后期限的镣铐(转载)
查看>>
Kth Smallest Element in a BST
查看>>
ubuntu14.04利用aliyun安装docker
查看>>