注意:这篇博客讲的是手写堆,喜欢用C++自带数据结构模拟的慎入

今天我们来聊一聊一种奇怪 的数据结构:

为什么说这个数据结构有点奇怪呢?

先看看其他的在我眼里是正常的数据结构:

队列(近似于排队)

栈(类似于一个桶)

数组(就是一组存储各种数据类型的集合(?))

但是!

堆这个东西有点奇怪,它模拟的是:

完全二叉树。

这就很让人摸不着头脑了emmmm

后来去各种找资料 知道了它的模拟方式就是:

堆的物理结构就是数组。堆的逻辑结构是一棵完全二叉树。树中每个结点与数组中存放该结点中值的那个元素相对应。如下图:



尼玛这不就是给这棵树的结点编号存数组里吗(疯狂咆哮)

接下来堆的特性我就找了一段资料如下,做了解就可以了:



感觉说的有点多…下面进入代码实现部分。今天我们以小根堆为例来进行代码实现的讲解 .

堆的基本操作:

  • 上浮(up)
  • 下沉(down)
  • 插入(insert)
  • 删除(del)
  • *建立(build)

第一个是上浮(up)操作。

上浮操作,顾名思义,就是将一个结点在树中的位置尽量往上浮

代码实现用到了【位运算】不了解的可以百度一下◀〓〓

基本思路:

以小根堆为例,当小根堆的元素值h[x]变小时,该结点可能会上浮,如果h[x]小于h[x>>1]则交换两个结点的值,如此循环下去直到x=1或h[x]>=h[x>>1].

e.g.





代码实现:

void up(int x)//h[x]上浮
{
   while (x>1&&h[x]<h[x>>1]){
       swap(h[x],h[x>>1]);
       x>>=1;
   }
}

时间复杂度为O(logn)。

下沉(down)操作:

思路:

当小根堆的元素值h[x]变大时,该结点可能会下沉,如果有儿子结点值小于该结点的值则跟较小儿子结点交换,如此循环下去直到条件不满足或者没有儿子结点。

代码:

void down(int x)//h[x]下沉,len是堆中元素个数
{
    int y=x<<1;
    while(y<=len){
         if(y+1<=len&&h[y+1]<h[y])y++;
         if(h[y]<h[x]){
               swap(h[x],h[y]);
               x=y;y=x<<1;
         }
         else break;
    }
}

O(logn)

插入(insert)操作:

基本思路:

插入一个元素,把该元素放在最后,再做up操作。

程序如下:

void insert(int x)
{
   h[++len]=x;
   up(len);
}

时间复杂度为O(logn)

删除(del)操作:

基本思路:

删除第x个元素,为了不破坏堆的性质,把h[len]移到x处,堆元素个数len减一,注意可能是做up(x)也可能做down(x),根据h[x]的变化情况来定。

程序如下:

void del(int x)//删除h[x]
{
    h[x]=h[len--];
    up(x);
    down(x);
}

时间复杂度为O(logn)

*建堆(build)操作



不做过多讲述,这个操作写法有很多,也可以尝试着自己去探索其他的写法!

ov.

【基本数据结构之堆】-C++的更多相关文章

  1. 算法手记 之 数据结构(堆)(POJ 2051)

    一篇读书笔记 书籍简评:<ACM/ICPC 算法训练教程>这本书是余立功主编的,代码来自南京理工大学ACM集训队代码库,所以小编看过之后发现确实很实用,适合集训的时候刷题啊~~,当时是听了 ...

  2. 数据结构之堆Heap

    1. 概述 堆(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆).它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等. 2. 堆 ...

  3. Java数据结构之堆和优先队列

    概述 在谈堆之前,我们先了解什么是优先队列.我们每天都在排队,银行,医院,购物都得排队.排在队首先处理事情,处理完才能从这个队伍离开,又有新的人来排在队尾.但仅仅这样就能满足我们生活需求吗,明显不能. ...

  4. python数据结构之堆(heap)

    本篇学习内容为堆的性质.python实现插入与删除操作.堆复杂度表.python内置方法生成堆. 区分堆(heap)与栈(stack):堆与二叉树有关,像一堆金字塔型泥沙:而栈像一个直立垃圾桶,一列下 ...

  5. 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...

  6. 数据结构:堆(Heap)

    堆就是用数组实现的二叉树,所有它没有使用父指针或者子指针.堆根据"堆属性"来排序,"堆属性"决定了树中节点的位置. 堆的常用方法: 构建优先队列 支持堆排序 快 ...

  7. 算法&数据结构系列 -- 堆(优先队列)

    前言 话说新开的博客十分好用... 所以,我打算开一个坑,名曰[算法系列]. 什么意思--从名字泥应该就猜得出来... 废话不多说,进入正文~~ 正文 原理 首先,堆是一颗棵二叉树.. 其次,堆是一棵 ...

  8. java数据结构之(堆)栈

    (堆)栈概述栈是一种特殊的线性表,是操作受限的线性表栈的定义和特点•定义:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈•特点:先进后出(FILO)或后进先出(L ...

  9. 数据结构(堆):POJ 1442 Black Box

    Black Box Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10658   Accepted: 4390 Descri ...

随机推荐

  1. 浅谈.NET编译时注入(C#-->IL)

    原文:浅谈.NET编译时注入(C#-->IL) .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台.所以.NET语言的编译就分为了两部 ...

  2. Advanced Installer 中测试数据库连接提示“未发现数据源名称并且未指定默认驱动程序”的解决办法

    原文:Advanced Installer 中测试数据库连接提示"未发现数据源名称并且未指定默认驱动程序"的解决办法 最近需要制作一个安装包,安装包的要求如下: 1.用户手工填写M ...

  3. oracle延迟块清除

    oracle在执行一些DML操作时,会在block上有活动事务的标志,如果一个事务commit后,由于某些block在commit之前已经写回datafile, 或者事务影响到的block数过多,则c ...

  4. MongoDB对文档的操作

    插入文档 db.COLLECTION_NAME.insert({doc1},{doc2},...) e.g.:db.collection.insert({name:'123',age:12},{nam ...

  5. Qt5图形视图框架的“俄罗斯方块”(使用了QGraphicsView)

    Qt5 图形视图框架QGraphicsView 1.图形视图框架包含三大类:场景类(QGraphicsScene),视图类(QGraphicsView),图元类(QGraphicsItem): 2.对 ...

  6. XPath概述

    1.  XPath 具体示例可参考网址: http://www.zvon.org/xxl/XPathTutorial/General/examples.html 1.1 概述 * 现节点下所有元素 * ...

  7. kafka设计原理(转)

    一.kafka简介 1.1 背景历史 当今社会各种应用系统,诸如商业.社交.搜索.浏览等信息工厂一样不断被生产出各种信息,在大数据时代,我们面临如下几个挑战: 如何收集这些巨大的信息 如何分析它 如何 ...

  8. pycharm安装及配置全过程

    首先要准备两个文件,一是pycharm-community,二是python-3.7.2-amd. PyCharm 的下载地址:http://www.jetbrains.com/pycharm/dow ...

  9. .NET程序员如何快入门Spring Boot

    本篇文章将教你作为一个.NET程序员如何快入门Spring Boot.你不需要用Eclipse,也不需要用IDEA.已经习惯了VS,其他的IDE-- 但不得不说VS Code很厉害,一用就喜欢.微软给 ...

  10. sublimetext插件安装

    sublimetext 一.下载地址: https://www.sublimetext.com/ 二.安装Package Control 方式一: Ctrl + Shift + P , 输入insta ...