预备知识: 

  完全二叉树的定义:一个深度为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准没错。。。

(日后可能更新)

<知识整理>树--堆及其应用的更多相关文章

  1. Redis相关知识整理

    Redis相关知识整理 1. Redis和MySQL的区别?a).mysql是关系型数据库,而redis是NOSQL,非关系型数据库.mysql将数据持久化到硬盘,读取数据慢,而redis数据先存储在 ...

  2. Linux系统基础知识整理

    一.说明 本篇文章,我将结合自己的实践以及简介,来对linux系统做一个直观清晰的介绍,使得哪些刚接触Linux的小伙伴可以快速入门,也方便自己以后进行复习查阅. 二.基本知识整理 1.Linux文件 ...

  3. C++进阶4.C++知识整理

    C++知识整理(多益笔试) 20131012 前言: 还是关于笔试知识的整理,主要是面向对象的知识还有一些常见的语法知识. 1.还是C++内存管理的知识 C++中程序的内存分布如下: 栈:向下增长,可 ...

  4. Linux系统基础知识整理(一)

    本文来自于: https://www.cnblogs.com/hafiz/p/6686187.html#4196989 一.说明 本篇文章,我将结合自己的实践以及简介,来对linux系统做一个直观清晰 ...

  5. js事件(Event)知识整理

    事件(Event)知识整理,本文由网上资料整理而来,需要的朋友可以参考下   鼠标事件 鼠标移动到目标元素上的那一刻,首先触发mouseover 之后如果光标继续在元素上移动,则不断触发mousemo ...

  6. Kali Linux渗透基础知识整理(四):维持访问

    Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...

  7. Kali Linux渗透基础知识整理(二)漏洞扫描

    Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网 ...

  8. wifi基础知识整理

    转自 :http://blog.chinaunix.net/uid-9525959-id-3326047.html WIFI基本知识整理 这里对wifi的802.11协议中比较常见的知识做一个基本的总 ...

  9. 数据库知识整理<一>

    关系型数据库知识整理: 一,关系型数据库管理系统简介: 1.1使用数据库的原因: 降低存储数据的冗余度 提高数据的一致性 可以建立数据库所遵循的标准 储存数据可以共享 便于维护数据的完整性 能够实现数 ...

随机推荐

  1. vue 单文件组件中样式加载

    在写单文件组件时,一般都是把标签.脚本.样式写到一起,这样写个人感觉有点不够简洁,所以就想着把样式分离出去. 采用import加载样式 在局部作用域(scoped)采用@import加载进来的样式文件 ...

  2. 微信小程序 canvas 文字自动换行

    Page({ drawCanvas: function(ctx) {// 地址 ctx.setFontSize() ctx.setFillStyle('#9E7240') ctx.textAlign= ...

  3. 可编辑且宽度自适应input

    默认的input项是比较难看的,并且它的宽度还无法随着输入而变化,这样未免有些呆板,不过借助JavaScript可以达到宽度自适应的效果,下面为了方便使用了jQuery: <div class= ...

  4. vue的组件化运用(数据在两个组件互传,小问题总结)

    一.vue的组件化应用 首先,知道有哪些相关的属性需要用到,再慢慢去理解,运用. 1.两个vue页面 2. slot占位符(可用可不用) 3.props内置属性 4.watch监听函数 5.impor ...

  5. 「技巧」如何快速安装 Sketch 插件

    Sketch拥有强大丰富的插件,但是这些插件天各一方,四处查找下载地址非常麻烦.这里提供一个技巧,通过一个入口可以安装各种插件,基本涵盖了市面上所有靠谱的插件. 准备 Sketch54 Runner ...

  6. 4.26 IO流

  7. WEB框架-Django框架学习(二)- 模型层

    今日份整理为模型层 1.ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库, ...

  8. 使用FreeHttp强制登出微信公众号登陆状态(实现~原理)

    概述 我们使用的部分网站设计成一旦登录即不允许用户手动退出,现实场景中是没有问题的 但如果是在测试或调试过程中就会有强制登出的需求 如果当前使用的是PC浏览器,您或许可以通过调试模式清除保持登录信息的 ...

  9. Python--day06(深浅拷贝、元组、字典、集合)

    1.  深浅拷贝 1.1  值拷贝 s1直接将ls中存放的地址拿过来s1内部的值发生任何变化,s2都会随之变化 s1 = ['1','2','3','a']s2 = s1print(id(s1),id ...

  10. EXCEL记录

    ー.重要快捷键 Ctrl + F → 查找 Ctrl + H → 替换 Ctrl + G → 定位 Ctrl + 1 → 设置单元格格式 Ctrl + Enter → 一并输入多个单元格 Ctrl + ...