数组模拟堆(二)

简介: 例题,代码AcWing 838. 堆排序

三、例题,代码

AcWing 838. 堆排序

本题链接:AcWing 838. 堆排序

本博客给出本题截图:

image.png

关于本题

关于建堆操作,我们当然可以选择一个一个插入的方式,但是,时间复杂度O(nlogn),这里给一种更快的建堆方式:

for (int i = n / 2; i; i -- ) down(i);

这样我们建堆的时间复杂度就变成了O(n)

AC代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int h[N], cnt;
int n, m;
void down(int x)
{
    int t = x;
    if (x * 2 <= cnt && h[x * 2] < h[t]) t = x * 2;
    if (x * 2 + 1 <= cnt && h[x * 2 + 1] < h[t]) t = x * 2 + 1;
    if (t != x)
    {
        swap(h[t], h[x]);
        down(t);
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    cnt = n;
    for (int i = 1; i <= n; i ++ ) scanf("%d", &h[i]);
    for (int i = n / 2; i; i -- ) down(i);
    while (m -- )
    {
        printf("%d ", h[1]);
        h[1] = h[cnt];
        cnt --;
        down(1);
    }
    return 0;
}

AcWing 839. 模拟堆

本题链接:AcWing 839. 模拟堆

本博客给出本题截图:

image.png

image.png

关于本题

这里重新介绍一下交换函数:

因为题目中是删除第k个插入的元素,所以我们需要另外开两个不同的数组:

ph[k]的含义是第k个插入数在堆中的下标

hp[k]的含义是堆中第k个点是第几个插入的点,我们的swap函数重写后为

void heap_swap(int a, int b)
{
    swap(ph[hp[a]],ph[hp[b]]);
    swap(hp[a], hp[b]);
    swap(h[a], h[b]);
}

AC代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
int h[N], ph[N], hp[N], cnt;
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 (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2;
    if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 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()
{
    int n, m = 0;
    scanf("%d", &n);
    while (n -- )
    {
        char op[5];
        int k, x;
        scanf("%s", op);
        if (!strcmp(op, "I"))
        {
            scanf("%d", &x);
            cnt ++ ;
            m ++ ;
            ph[m] = cnt, hp[cnt] = m;
            h[cnt] = x;
            up(cnt);
        }
        else if (!strcmp(op, "PM")) printf("%d\n", h[1]);
        else if (!strcmp(op, "DM"))
        {
            heap_swap(1, cnt);
            cnt -- ;
            down(1);
        }
        else if (!strcmp(op, "D"))
        {
            scanf("%d", &k);
            k = ph[k];
            heap_swap(k, cnt);
            cnt -- ;
            up(k);
            down(k);
        }
        else
        {
            scanf("%d%d", &k, &x);
            k = ph[k];
            h[k] = x;
            up(k);
            down(k);
        }
    }
    return 0;
}

四、时间复杂度

关于手写堆各部操作的时间复杂度以及证明,后续会给出详细的说明以及证明过程,目前先鸽了。

目录
相关文章
|
2月前
|
存储
【数据结构】堆的模拟实现
【数据结构】堆的模拟实现
|
2月前
|
存储 算法 安全
堆的应用例子
【5月更文挑战第6天】堆栈是一种LIFO(后进先出)数据结构,支持push、pop、isEmpty、isFull和peek等操作。内部使用切片存储接口类型的元素
38 0
堆的应用例子
|
2月前
|
存储 算法
什么是堆,优先级队列的模拟实现
什么是堆,优先级队列的模拟实现
23 0
|
2月前
数据结构 模拟实现Stack栈(数组模拟)
数据结构 模拟实现Stack栈(数组模拟)
40 0
|
12月前
数组模拟链表、栈、队列
数组模拟链表、栈、队列
33 0
力扣155:最小栈(Java 辅助栈 -> 不使用额外空间)
力扣155:最小栈(Java 辅助栈 -> 不使用额外空间)
139 0
|
存储 算法 C++
数组模拟堆(一)
复习acwing算法基础课的内容,本篇为讲解基础算法:用数组模拟堆,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。
104 0
数组模拟堆(一)
|
Java
简洁明了,Java实现数组模拟栈,先进后出,栈顶为出入口
简洁明了,Java实现数组模拟栈,先进后出,栈顶为出入口
263 0
|
算法 C++
数组模拟栈
文章目录 前言 一、关于栈 二、栈的操作 1.数组模拟栈必备属性 2.把x插入到栈顶 3.把栈顶元素弹出 4.判断栈是否为空 5.查询栈顶元素 三、例题,代码 AcWing 828. 模拟栈 AC代码 四、时间复杂度
68 0
数组模拟栈

热门文章

最新文章

  • 1
    流量控制系统,用正则表达式提取汉字
    27
  • 2
    Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
    27
  • 3
    Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
    27
  • 4
    Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
    28
  • 5
    S外部函数可以访问函数内部的变量的闭包-闭包最简单的用不了,闭包是内层函数+外层函数的变量,简称为函数套函数,外部函数可以访问函数内部的变量,存在函数套函数
    25
  • 6
    Redis06-Redis常用的命令,模糊的搜索查询往往会对服务器产生很大的压力,MSET k1 v1 k2 v2 k3 v3 添加,DEL是删除的意思,EXISTS age 可以用来查询是否有存在1
    31
  • 7
    Redis05数据结构介绍,数据结构介绍,官方网站中看到
    23
  • 8
    JS字符串数据类型转换,字符串如何转成变量,+号只要有一个是字符串,就会把另外一个转成字符串,- * / 都会把数据转成数字类型,数字型控制台是蓝色,字符型控制台是黑色,
    21
  • 9
    JS数组操作---删除,arr.pop()方法从数组中删除最后一个元素,并返回该元素的值,arr.shift() 删除第一个值,arr.splice()方法,删除指定元素,arr.splice,从第一
    21
  • 10
    定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
    20