<知识整理>树--堆及其应用

预备知识:
完全二叉树的定义:一个深度为k数的二叉树(设根节点的深度为1),若二叉树深度从1到k-1层都是满的,而第k层的节点都集中在左边(即第k层不存在两节点之间有空缺),那么此数就被叫做完全二叉树。
完全二叉树有几个重要的性质(编号从根节点由1开始广度优先从左到右排):
编号为i的节点左儿子(如果有的话)的编号为2*i,右儿子(如果有的)的编号为2*i+1,父节点(如果有的话)的编号为i/2。由此还可知道i节点有父亲的充要条件是i/2>=1,有儿子的充要条件是i*2<=size(size为该完全二叉树最大点编号)
堆的概述:
堆(heap)用数组存储,可看做一个完全二叉树,数组元素的下标即树节点的编号,故可由上性质知a[i]的父亲(如果有的话)为a[i/2],左儿子和右儿子(如果有的话)分别为a[i*2]和a[i*2+1]。
大根堆:父亲>=儿子;小根堆:父亲<=儿子。由大小根堆定义知堆顶一定是大根堆里最大、小根堆里最小的元素。
堆的核心操作为put操作(向堆里添一个元素)和get操作(取出堆顶并删除)。
以小根堆为例讲解二操作:
put:1.在堆尾插入一个元素,设其为当前节点;
2.当前节点与其父亲(如果有的话,否则直接结束)比较;
3.若比父亲小,与父亲交换值,更新当前节点为父节点,并继续重复第2步:否则结束。
核心代码:
void put(int x)
{
heap[++heap_size]=x;
int now,next;//当前节点,父亲节点
now=heap_size;
while(now>)
{
next=now>>;
if(heap[now]>=heap[next]) return;
swap(heap[now],heap[next]);
now=next;
}
}
get:1.保存堆顶元素,让最后一个元素覆盖堆顶元素,堆的大小减一,设当前节点为根节点;
2.当前节点与其儿子(如果有的话,否则之间结束、返回保存的堆顶元素)中值最小的比较;
3.若比儿子大,交换它们的值,更新当前节点为该儿子节点,继续第2步比较;否则结束,并返回保存的堆顶元素。
核心代码:
int get()
{
int ans=heap[];
heap[]=heap[size--];
int now=,next;
while(now*<=size)
{
next=now*;
if(next<size&&heap[next+]<heap[next]) next++;//找到最小的儿子
if(heap[now]<=heap[next]) break;
swap(heap[next],heap[now]);
now=next;
}
return ans;
}
如为大根堆,只需比较时让大的“下潜”就行。
时间复杂度:都是O(log n)
应用:
1.堆排序:
由大小根堆定义知堆顶一定是大根堆里最大、小根堆里最小的元素,便可将待排元素一个个put到一个队里,并一个个get出来,时间复杂度为O(n log n)。
2.STL优先队列(实质是堆):特点是可以自动排序,详情见大佬博客:
https://blog.csdn.net/qq_19656301/article/details/82490601
~~~
最后BB:
可见堆的时间复杂度都是最坏情况的复杂度,个人认为数据极好的话堆排序应该比sort快。。。 不过普通数据用sort准没错。。。
(日后可能更新)
<知识整理>树--堆及其应用的更多相关文章
- Redis相关知识整理
Redis相关知识整理 1. Redis和MySQL的区别?a).mysql是关系型数据库,而redis是NOSQL,非关系型数据库.mysql将数据持久化到硬盘,读取数据慢,而redis数据先存储在 ...
- Linux系统基础知识整理
一.说明 本篇文章,我将结合自己的实践以及简介,来对linux系统做一个直观清晰的介绍,使得哪些刚接触Linux的小伙伴可以快速入门,也方便自己以后进行复习查阅. 二.基本知识整理 1.Linux文件 ...
- C++进阶4.C++知识整理
C++知识整理(多益笔试) 20131012 前言: 还是关于笔试知识的整理,主要是面向对象的知识还有一些常见的语法知识. 1.还是C++内存管理的知识 C++中程序的内存分布如下: 栈:向下增长,可 ...
- Linux系统基础知识整理(一)
本文来自于: https://www.cnblogs.com/hafiz/p/6686187.html#4196989 一.说明 本篇文章,我将结合自己的实践以及简介,来对linux系统做一个直观清晰 ...
- js事件(Event)知识整理
事件(Event)知识整理,本文由网上资料整理而来,需要的朋友可以参考下 鼠标事件 鼠标移动到目标元素上的那一刻,首先触发mouseover 之后如果光标继续在元素上移动,则不断触发mousemo ...
- Kali Linux渗透基础知识整理(四):维持访问
Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...
- Kali Linux渗透基础知识整理(二)漏洞扫描
Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网 ...
- wifi基础知识整理
转自 :http://blog.chinaunix.net/uid-9525959-id-3326047.html WIFI基本知识整理 这里对wifi的802.11协议中比较常见的知识做一个基本的总 ...
- 数据库知识整理<一>
关系型数据库知识整理: 一,关系型数据库管理系统简介: 1.1使用数据库的原因: 降低存储数据的冗余度 提高数据的一致性 可以建立数据库所遵循的标准 储存数据可以共享 便于维护数据的完整性 能够实现数 ...
随机推荐
- 学习笔记—JDBC
JDBC的概念 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言 ...
- vue+element-ui实现行数可控的表格输入
element的table中使用 <template slot-scope="scope"> </template> 包裹想要插入的input,或者sele ...
- 时空地图TimeGIS.com生成正交曲线网格
数值模拟中对数学物理方程的求解过程中经常需要生成网格,这里提供了一种方便的方法,只需要简单地勾画出区域的轮廓, 就可以生成相应的正交曲线网格,详情请访问 www.TimeGIS.com
- Python绘图与可视化
Python有很多可视化工具,本篇只介绍Matplotlib. Matplotlib是一种2D的绘图库,它可以支持硬拷贝和跨系统的交互,它可以在Python脚本.IPython的交互环境下.Web应用 ...
- Linux网络基本网络配置方法介绍
网络信息查看 设置网络地址: cat /etc/sysconfig/network-scripts/ifcfg-eth0 你将会看到: DEVICE=eth0BOOTPROTO=staticsHWAD ...
- MongoDB自学(2)
条件操作符: gt(大于),gte(大于等于),lt(小于),lte(小于等于)E.G:db.People.find({age:{$gt:100}})//查找集合里age大于100的文档 注意:str ...
- Ngnix负载均衡安装及配置
1.ngnix概念 Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5 ...
- SQL Server 取日期时间格式 日期与字符串之间的转换
SQL Server 取日期时间部分 在本文中,GetDate()获得的日期由两部分组成,分别是今天的日期和当时的时间: Select GetDate() 用DateName()就可以获得相应的 ...
- Windows Cluster 在群集管理器下 集群或可用性组 都不显示的问题
作为一个IT成员,特别是偏支持的.很多时候就是和各种异常打交道,总会碰到一些奇奇怪怪的问题.很多时候,可能是一个小小的异常都需要花费很长时间去解决. SQL Server AlwaysOn 是建立在W ...
- Linux学习历程——Centos 7 passwd命令
一.命令介绍 passwd 命令用于修改用户密码,过期时间,认证信息等. 普通用户只能使用 passwd 命令修改自身的系统密码,而 root 管理员则有权限修改其他所有人的密码.更酷的是,root ...