基础数据结构

news2024/9/24 7:26:18

1. 单链表

#include<iostream>

using namespace std;
const int N = 1e5 + 10;

int n;
// 分别存储当前节点的值,当前节点下一个节点的值,头结点,id号
int value[N], nepoint[N], head, idx;

void init(){
    head = -1;
    idx = 0;
    
}

// 1.H 将某个x插入到头结点上
void int_to_head(int x){
    value[idx] = x;// 初始化节点的值
    nepoint[idx] = head;// 初始化头结点的下一个节点,头插法
    head = idx;// 改变头结点
    idx++;
    
}

// 2.删除
void remove(int k){
    nepoint[k] = nepoint[nepoint[k]];
}


// 3.添加
void add(int k, int x){
    value[idx] = x;
    nepoint[idx] = nepoint[k];
    nepoint[k] = idx;
    idx++;
}
int main(){
    cin >> n;
    init();//初始化链表
    for (int i = 0; i < n; i++) {
        char s;
        cin >> s;
        if (s == 'H'){
            int x;
            cin >> x;
            int_to_head(x);
        }
        if (s == 'D'){
            int k;
            cin >> k;
            if (k == 0) head = nepoint[head];
            else remove(k - 1);
        }
        if (s == 'I'){
            int k, x;
            cin >> k >> x;
            add(k - 1, x);// 找到 k 的前一个元素,利用它进行插入
        }
    }
    for (int i = head; i != -1; i = nepoint[i]){
        cout << value[i] << ' ';
    }
    return 0;
}

2. 双链表

#include<iostream>
using namespace std;
const int N = 1e5+10;

int e[N], l[N], r[N];

int m, idx;

void init(){
    r[0] = 1;
    l[1] = 0;
    // 1.idx 从 2 开始。我们插入的第i个数的idx为i+1
    idx = 2;
}

// 在第k个插入的数右边插入x
void add(int k, int x){
    e[idx] = x;
    r[idx] = r[k];
    l[idx] = k;
    l[r[k]] = idx;
    r[k] = idx;
    // 2.要让idx++
    idx++;
}

void remove(int k){
    r[l[k]] = r[k];
    l[r[k]] = l[k];
}


int main(){
    cin >> m;
    init();
    while(m--){
        string op;
        cin >> op;
        int k, x;
        if (op == "R"){
            cin >> x;
            // 在尾节点左边的一个节点的右边插入
            add(l[1], x);
        }else if (op == "L"){
            cin >> x;
            // 在头结点的右边插入
            add(0, x);
        }else if (op == "D"){
            cin >> k;
            // k 和 k + 1 的对应关系
            remove(k + 1);
        }else if (op == "IL"){
            cin >> k >> x;
            add(l[k + 1], x);
        }else{
            cin >> k >> x;
            add(k + 1, x);
        }
    }
    // 3.注意!头结点不用输出,所以第一个输出的是r[0]
    // 尾节点也不用输出
    // 不断推进
    for (int i = r[0]; i != 1; i = r[i]){
        cout << e[i] << " ";
    }

}

3. 模拟栈

#include<iostream>
using namespace std;

const int N = 1e5 + 10;
int top = -1;// 栈顶元素为空
int v[N];

int main(){
    int n;
    cin >> n;
    while(n--){
        string s;
        cin >> s;
        if (s == "push")
        {
            int a;
            cin >> a;
            v[++top] = a;// 更新栈顶元素
        }
        if (s == "pop")
        {
            top--;// 移动栈顶指针
        }
        if (s == "query")
        {
            cout << v[top] << endl;
        }
        if (s == "empty")
        {
            cout << (top == -1 ? "YES" : "NO") << endl;
        }
    }
}

4. 模拟队列

#include<iostream>
using namespace std;
const int N = 1e5+10;
int q[N];

int main(){
    int n;
    cin >> n;
    int h = 0, t = -1;
    while(n--){
        string op;
        cin >> op;
        int x;
        if (op == "push"){
            cin >> x;
            q[++t] = x;
        }else if (op == "pop"){
            h++;
        }else if (op == "empty"){
            if (h <= t) puts("NO");
            else puts("YES");
        }else {
            cout << q[h] << endl;
        }
    }
}

5. 单调栈

#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int stk[N], t;

int main(){
    int n;
    cin >> n;
    while(n--){
        int x;
        scanf("%d", &x);

        // 如果栈非空,检查其中是否有 >= x 的元素,如果有要清空
        while(t && stk[t] >= x) t--;
        // 如果栈是空的,打印 -1
        if (!t) cout << -1 << ' ';
        // 如果栈是非空的,打印栈顶元素
        else cout << stk[t] << " ";
        // 将新来的元素加入栈
        stk[++t] = x;
    }
    return 0;
}

6. 模拟堆

down: 往下调整,

up: 往上调整

插入:heap[s++] = x, up(size)

求最小:heap[1]

删除:swap[heap[1], heap[size]], size--, down[1] 删除头元素很麻烦

删除任意元素:heap[k] = heap[size]; size--; down(k), up(k)

修改元素:heap[k] = x; down(k), up(k)

#include<iostream>
#include<algorithm>
#include<string.h>

using namespace std;

const int N = 1e5 + 10;

int h[N], ph[N], hp[N], cnt;

// ph[1] = a, hp[a] = 1
void heap_swap(int a, int b)
{
    swap(ph[hp[a]], ph[hp[b]]);
    swap(hp[a], hp[b]);
    // 交换堆中存储的 a 和 b 位置的值
    swap(h[a], h[b]);
}

// 对堆中位置在 u 的元素执行
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 = 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()
{
    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);
            // 更新 size
            cnt++;
            // 唯一 ID 表示当前是第 m 个插入的数
            m++;
            // size 和 ID 建立联系
            ph[m] = cnt, hp[cnt] = m;

            h[cnt] = x;
            up(cnt);
        }
        // h[1] 存储的是最小的元素
        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;
}

7. 堆排序

从 n/2 开始 down,复杂度为 O(n)

#include<iostream>
#include<algorithm>// 因为需要调用swap
using namespace std;
const int N = 1e5 + 10;

int h[N], Msize;//堆的大小

int n, m;

void down(int u){
    int t = u;
    // 判断左右孩子是否存在以及他们的大小
    // 更新 t 为最小的元素下标
    if(u*2 <= Msize && h[u*2] < h[t]) t = u*2;
    if(u*2 + 1 <= Msize && h[u*2 + 1] < h[t]) t = u*2 + 1;
    if(u != t){
        swap(h[u], h[t]);
        down(t);
    }
}

int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &h[i]);
    Msize = n;
    // 收敛性证明:错位相减
    for(int i = n / 2;i;i--) down(i);
    while(m--){
        cout << h[1] << " ";
        h[1] = h[Msize--];
        down(1);
    }

    return 0;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364968.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker学习与应用(三)-Docker镜像理解

1、Docker镜像讲解 1&#xff09;镜像是什么 镜像是一种轻量级、可执行的独立软件包&#xff0c;用来打包软件运行环境和基于运行环境开发的软件&#xff0c;他包含运行某个软件所需的所有内容&#xff0c;包括代码、运行时库、环境变量和配置文件。 所有的应用&#xff0c;…

在 PyCharm 中高效使用 GitHub Copilot

对于每一个developer来说&#xff0c;工具和插件对于提高开发效率至关重要。GitHub Copilot&#xff0c;作为一款先进的人工智能编程助手&#xff0c;能够在编写代码时提供实时建议和自动补全功能。结合 PyCharm 这一强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c…

web期末个人引导页透明版

效果图 代码 css代码 * {box-sizing: border-box; }body {color: #2b2c48;font-family: "Jost", sans-serif;background-image: url(../img/bg.jpg);background-repeat: no-repeat;background-size: cover;background-position: center;background-attachment: fix…

Windows系统任务栏应用图标显示成空白的解决方案

背景 任务栏应用图标为空白&#xff1a; 原因 Windows系统为了加快系统响应速度&#xff0c;在安装完应用第一次显示完应用图标后&#xff0c;会将应用的图标放入缓存中&#xff0c;以后每次显示应用直接在缓存中获取&#xff0c;如果缓存中的图标信息发生错误&#xff0c;…

OpenCV | 光流估计

光流估计 光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”&#xff0c;根据各个像素点的速度的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪 高度恒定&#xff1a;同一点随着时间的变化&#xff0c;其亮度不会发生改变。小运动&…

Maven之属性管理

1.属性管理 1.1 属性配置与使用 ①&#xff1a;定义属性 <!--定义自定义属性--> <properties><spring.version>5.2.10.RELEASE</spring.version> </properties>②&#xff1a;引用属性 <dependency><groupId>org.springframewor…

王力机器人安全门|用细节开拓高端精致家居生活

细微之处见风范,毫厘之优定乾坤。在追求高端品质的道路上,细节往往是最有力的诠释。如在入户门的选择方面,考虑到老人、孩子、宠物等每一位家庭成员不同需求的设计、科技运用才称得上是充满人性化、品质化的高端细节,幸福感直抵心灵。在该方面,王力机器人安全门做出了表率,每一…

快速实现产品智能:用 AI 武装你的 API | 开源日报 No.138

openchatai/OpenCopilot Stars: 3.8k License: MIT OpenCopilot 是一个允许你拥有自己产品的 AI 副驾驶员的项目。它集成了产品底层 API&#xff0c;并可以在需要时执行 API 调用。它使用 LLMs 来确定用户请求是否需要调用 API 端点&#xff0c;然后决定调用哪个端点并根据给定…

2024.1.3力扣每日一题——从链表中移除节点

2024.1.3 题目来源我的题解方法一 递归方法二 栈方法三 反转链表方法四 单调栈头插法 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2487 我的题解 方法一 递归 当前节点对其右侧节点是否删除无影响&#xff0c;因此可以对其右侧节点进行递归移除。 若当前节点为空&am…

嵌入式(七)看门狗 | 看门狗工作模式 寄存器 时钟系统

文章目录 1 看门狗原理2 功能3 看门狗工作模式4 看门狗控制寄存器5 时钟系统 及其寄存器 1 看门狗原理 看门狗(Watch Dog Timer&#xff0c; WDT)是一种专门用于监测单片机程序运行状态的芯片组件。其实质是一个计数器&#xff0c;一般给看门狗初始一个比较大的数&#xff0c;…

【量化】一文整理所有日历效应,持股还是不持股过节清楚明了

日历效应&#xff08;Calendar Effect&#xff09;是指在特定的日期或时间段内&#xff0c;金融市场或经济活动中出现的统计上的规律或周期性现象。这些规律可能与特定日期、星期几、月份或季节等时间因素有关。根据众多研究者多年的研究总结&#xff0c;我们可以将日历效应划分…

Kali Linux——VMware安装Kali

目录 一、下载Kali Linux 1、选择下载安装程序映像或者预构建映像 2、下载安装程序映像 3、下载虚拟机预构建映像 二、安装Kali Linux &#xff08;一&#xff09;使用安装程序映像安装&#xff08;iso文件&#xff09; &#xff08;二&#xff09;使用虚拟机预构建映像安…

探索 2024 年:未来可能带来的新奇事物

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【基础工具篇使用】VScode 远程 Ubuntu 系统 进行使用

文章目录 准备条件使用步骤step1&#xff1a; 打开远程窗口step2&#xff1a;选择中的红色框“Connect to Host”功能Step3: 根据图中的红色框提示信息输入远程电脑的用户名和 IP 地址&#xff0c;输入如下命令即可连接&#xff1a; 显示效果 准备条件 我们可以使用 vscode 的…

【已解决】在开启ssh和sshd状态下,XShell无法连接到VMware虚拟机中的Linux操作系统

【已解决】在开启ssh和sshd状态下&#xff0c;XShell无法连接到VMware虚拟机中的Linux操作系统 XShell无法连接到VMware虚拟机中的Linux操作系统&#xff0c;今天上线突然发现XShell无法连接到VMware虚拟机中的Linux操作系统&#xff0c;但是找了很多解决方案都没有解决&#x…

odoo17 | 模型视图继承

前言 Odoo的强大之处在于它的模块化。模块专门用于满足业务需求&#xff0c;但模块也可以彼此交互。这对于扩展现有模块的功能非常有用。例如&#xff0c;在我们的房地产场景中&#xff0c;我们希望在常规用户视图中直接显示销售人员的属性列表。 但是在讨论特定的Odoo模块继…

Java 开源扫雷游戏 JMine 发布介绍视频

Java 开源扫雷游戏 JMine 发布介绍视频 Java 开源扫雷游戏 JMine 是笔者开发的基于 Swing 的 Java 扫雷游戏&#xff0c;现已发布介绍视频。视频请见&#xff1a;https://www.bilibili.com/video/BV1Qe411m7qM/ JMine 比较重视的还原了微软的扫雷游戏。在算法设计中&#xff…

【EAI 004】LLM+P:借助LLM和PDDL赋予机器人最优规划能力

论文标题&#xff1a;LLMP: Empowering Large Language Models with Optimal Planning Proficiency 论文作者&#xff1a;Bo Liu, Yuqian Jiang, Xiaohan Zhang, Qiang Liu, Shiqi Zhang, Joydeep Biswas, Peter Stone 作者单位&#xff1a;Department of Computer Science, Th…

WorkPlus Meet打造高质量的视频会议体验,助力实时远程协作

在全球化的商业环境中&#xff0c;远程协作和在线会议成为了企业高效工作的关键。作为一款高质量的视频会议软件&#xff0c;WorkPlus Meet以其卓越的性能和创新的功能&#xff0c;成为企业实时远程协作的首选。 WorkPlus Meet打造了高质量的视频会议体验&#xff0c;为企业提供…

Transformer - Attention is all you need 论文阅读

虽然是跑路来NLP&#xff0c;但是还是立flag说要做个project&#xff0c;结果kaggle上的入门project给的例子用的是BERT&#xff0c;还提到这一方法属于transformer&#xff0c;所以大概率读完这一篇之后&#xff0c;会再看BERT的论文这个样子。 在李宏毅的NLP课程中多次提到了…