第二章 数据结构(二)(堆)

一、堆(下标从1开始)

小顶堆:每个点都小于等于左右结点

数组的方式存储、down和up操作实现各种操作。在小顶堆中一个点变小了应该向上更新(只要比父节点小就交换),一个结点变大了就往下走(只要)

1、插入一个数:从数组末尾加数,从下往上更新

heap[++size]=x;up(size);

2、获取最小值:heap[1]

3、删除堆顶的元素:用堆尾更新堆顶,从上往下更新;删除堆尾很方便

heap[1]=heap[size];size--;down(1);

4、删除第k个结点,用尾结点更新第k位结点;

heap[k]=heap[size];size--;down(k);up(k);

3、修改一个元素 

heap[k]=x;down(k);up(k);

4、down操作的时间复杂度

第二章 数据结构(二)(堆)_第1张图片

5、堆排序:输出前m个小的数

#include
//838手写堆
using namespace std;
const int N=1e5+10;
int n,m;
int h[N],sizee;
void down(int u)
{
//就是要找出down的时候要交换的位置下标,交换后,递归
    int t=u;//将小的和下面交换
    if(u*2<=sizee&&h[u*2]=1;i--)down(i);
   while(m--)
   {
       cout<

6、模拟堆的各种操作,维护hp数组保存堆中某个位置的数是第几个插入的;维护ph数组保存第几个插入的数是几;

  1. I x,插入一个数 x;
  2. PM,输出当前集合中的最小值;
  3. DM,删除当前集合中的最小值(数据保证此时的最小值唯一);
  4. D k,删除第 k 个插入的数;
  5. C k x,修改第 k个插入的数,将其变为 x;
#include
//838手写堆
using namespace std;
const int N=1e5+10;
int n,m=0;
int h[N],sizee;
int ph[N];//ph[k]=i 第k个插入的数在堆里面插入的下标是什么
int hp[N];//同时在堆中某个位置的点也需要知道是第几个插入的数指向的
void heap_swap(int a,int b)
{
    swap(h[a],h[b]);//结点的值进行交换
    swap(hp[a],hp[b]);//更新堆中某个位置的点是第几个插入的点
    swap(ph[hp[a]],ph[hp[b]]);//更新堆中下标指向的第几个插入的点


}
//小顶堆:一个结点变大只有可能会影响到后面
//down操作需要更新
void down(int u)
{
    int t=u;
    if(u*2<=sizee&&h[u*2]h[u])
    {
        heap_swap(u,u/2);
        u/=2;
    }
}
int main()
{

   scanf("%d%d",&n);
   int size=0;
   //for(int i=1;i<=n;i++)scanf("%d",&h[i]);
//   sizee=n;
//   //构造堆
//   for(int i=n/2;i>=1;i--)down(i);
//   while(m--)//输出前m个小的数
//   {
//       cout<

7、

你可能感兴趣的:(蓝桥准备,数据结构,算法)