如何手写一个堆

下标从1开始,如果从0开始的话,他的左儿子的下标就等于0*2 = 0,麻烦

手写堆可以实现的操作:1,插入一个数  2,求集合当中的最小值  3,删除最小值

4,删除任意一个元素  5,修改任意一个元素(stl中的堆不能直接实现功能四五,可以间接实现)

堆是一颗完全二叉树

以小根堆为例,根结点小于等于他的子节点,所以小根堆的根节点是最小的值

堆用一个一维数组存储,图中的x指下标

刚开始输入所有值之后维护这棵树,让他成为堆的方法

从倒数第二层开始往下down,倒数第二层的down执行一次,倒数第三层执行两次.....

总共的时间复杂度算下来是O(n)

堆的基本操作:

down(),up(),上面的五种操作全部可以用这两个拼接出来

down就是在父亲结点比儿子节点大了,然后在两个儿子结点中找一个最小的,然后和他交换,直到不再需要交换为止

up操作中小的子节点只需要和父节点进行比较然后交换

堆排序

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<unordered_map>using namespace std;const int N = 100010;int m, n;
int h[N], siz;void down(int u)
{int t = u;if (u * 2 <= siz && h[u * 2] < h[u]) t = u * 2;if (u * 2 + 1 <= siz && h[t] > h[u * 2 + 1]) t = u * 2 + 1;if (t != u){swap(h[t], h[u]);down(t);}
}int main()
{cin >> n >> m;for (int i = 1; i <= n; i++) cin >> h[i];siz = n;for (int i = n / 2; i >= 1; i--) down(i);while (m--){cout << h[1] << ' ';h[1] = h[siz];siz--;down(1);}return 0;
}

 这里要把与siz的比较放在前面,否则会出现segmentation fault的错误

模拟堆

hp数组是用数的下标得到插入顺序

ph数组是根据插入顺序得到数的下标

在交换两个数的时候需要先交换idx指向堆的关系,接着交换堆指向idx的关系,最后在将值进行交换

#include<iostream>
#include<algorithm>
#include<cstring>using namespace std;const int N = 100010;int n;
int h[N],hp[N],ph[N],cnt;//如果要删除的是第k个数,那么直接交换就可以了,但是插入的是第k个插入的数,所以就需要idx来记录插入的顺序
//因为有idx来记录,所以idx和点之间就会存在联系,但是无法通过值来查找对应的idx,所以在原来ph【】数组的基础上,需要引进hp【】数组
//从而通过hp【i】 =  idx (i表示在数组中的第i位,idx表示在第idx次插入的数),有了hp【】数组的表示,
//那么我们就可以通过ph【】来找到第idx位插入的数字在第数组的第i位。
//所以在执行交换操作是的时候,我们要先交换idx指向堆的关系,接着交换堆指向idx的关系,最后在将值进行交换
void heap_swap(int a,int b)
{swap(ph[hp[a]],ph[hp[b]]);swap(hp[a],hp[b]);swap(h[a],h[b]);
}void down(int u)
{int t = u;if(2 * u <=cnt && h[2 * u ] < h[t] ) t = 2 * u;if(2 * u + 1 <= cnt && h[2 * u + 1 ] < h[t]) t = 2 * u + 1;if(u != t){heap_swap(u,t);down(t);}
}void up(int u)
{while(u / 2 && h[u] < h[u / 2]){heap_swap(u,u / 2);u >>= 1;}
}int main()
{cin>>n;int idx = 0;while(n -- ){char op[5];int k , x;cin>>op;if(!strcmp(op,"I")){cin>>x;cnt ++;idx ++;ph[idx] = cnt;hp[cnt] = idx;h[cnt] = x;up(cnt);}else if(!strcmp(op,"PM")) cout<<h[1]<<endl;else if(!strcmp(op,"DM")){heap_swap(1,cnt);cnt --;down(1);}else if(!strcmp(op,"D")){cin>>k;k = ph[k];heap_swap(k,cnt);cnt --;up(k),down(k);}else{cin>>k>>x;k = ph[k];h[k] = x;up(k),down(k);}}return 0;
}

堆(堆排序和模拟堆)相关推荐

  1. 堆 AcWing 839. 模拟堆

    堆 AcWing 839. 模拟堆 原题链接 AcWing 839. 模拟堆 算法标签 堆 思路 由于题目需要支持随机修改删除, 因此需要存储每个节点映射 摘自该题解 交换过程 对应代码 void h ...

  2. Day10 堆排序、模拟堆 trie树(字典树) 并查集

    堆呢就是一棵树完全二叉树... 小根堆的话,根节点就是最小值 维护堆只有两个操作 up(k) down(k) cnt是堆的大小 建堆的话只需要把前n/2的数down下来就ok 复杂度是小于O(n) 的 ...

  3. 堆(手写堆包含STL)

     文章目录 前言 一.堆的定义 二.堆的分类及性质(STL的用法) 1.堆的分类 2.STL的用法 3.堆的性质 三.手写堆(重点) 1.手写堆的思想 2.函数模块 3.操作模块 四.完整代码 + 注 ...

  4. 堆排序(浅谈大顶堆与小顶堆)

    什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被看作一个完全二叉树,通俗来讲堆其实就是利用完全二叉树的结构来维护的一维数组,按照堆的特点可以把堆分为大顶堆 ...

  5. c语言标准模板小顶堆,堆排序(大顶堆、小顶堆)----C语言

    堆排序 之前的随笔写了栈(顺序栈.链式栈).队列(循环队列.链式队列).链表.二叉树,这次随笔来写堆 1.什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被 ...

  6. AcWing 839.模拟堆

    对于堆介绍可以看这篇博客 Acwing 838.堆排序_m0_50564748的博客-CSDN博客 这篇主要讲一下,如何找到第k个插入的数. 那么此时需要额外的两个数组来进行记录,分别是ph[k],h ...

  7. 堆排序之 大顶堆和小顶堆 c语言

    百度得到的堆定义如下: 堆的定义如下:n个元素的序列{k1,k2,ki,-,kn}当且仅当满足下关系时,称之为堆. (ki <= k2i,ki <= k2i+1)或者(ki >= k ...

  8. php堆是什么,PHP 堆与堆排序的详解

    堆排序:堆排序是利用堆的性质进行的一种选择排序.下面先讨论一下堆. 1.堆 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i ...

  9. AcWing 839. 模拟堆

    题目链接 https://www.acwing.com/problem/content/841/ 思路 纯纯模拟堆的操作,后面细说,可以先看代码 代码 #include<bits/stdc++. ...

最新文章

  1. editplus 3 注册码
  2. C++_复合、委托、继承
  3. 浅析日常网站建设中运营与优化的工作重点
  4. mysql创建表的时候显式申明存储引擎
  5. JSP Cookie案例
  6. 安卓没删干净导致报错
  7. iOS官方Sample大全
  8. cmos摄像头如何识别颜色_绝对实用!开车上路怕违章 教你如何识别各种违章摄像头...
  9. android 获取serialno_[Android]关于Android 唯一设备号(ro.serialno)
  10. 牛客网【每日一题】7月31日题目精讲—兔子的区间密码
  11. MySQL运算符,SQL,算术比较逻辑位,优先级,正则表达式,完整详细可收藏
  12. 【一鸣离职,左晖去世】互联网老兵给大家的三个建议
  13. python语法_str_eval
  14. 7.7_adadelta
  15. BI项目篇——项目启动
  16. 如何把几张图片合并成一张图片?
  17. 经典的java角色扮演,盘点2010年十大经典角色扮演类游戏合集
  18. 停车场管理系统可行性研究报告
  19. BottomNavigationView+ViewPager+Fragment 底部导航按钮
  20. c语言阿基米德螺旋线编程,阿基米德螺旋线进刀凸轮外轮廓铣削的编程技巧

热门文章

  1. 承德石油高等专科学校计算机20019年,承德石油高等专科学校2019年高职单招录取人数...
  2. Page和PageInfo
  3. 明渠流量计比对装置是做什么用的?
  4. 最短路模型-跳楼机-洛谷P3403
  5. Asp.net WebAPI Attribute Rout
  6. 蓝桥 历届试题 核桃的数量
  7. 49 款人脸检测/识别的API、库和软件 .
  8. input文本框的提示效果
  9. Learn OpenGL - 使用GLEW
  10. Radware 警告下一轮 DDoS 攻击