数组模拟几种基本的数据结构

文章目录

  • 数组模拟单链表
  • 数组模拟双链表
  • 数组实现栈
  • 数组模拟队列
  • 总结

在这里插入图片描述

数组模拟单链表

首先类比结构体存储单链表,我们需要一个存放下一个节点下标的数组,还需要一个存储当前节点的值的数组,其次就是一个int类型的索引,这个索引指向的是下一个我们准备用的空间,还需要一个head,head存放的是头结点的下标

我们用下面一道题来更深刻的理解*

在这里插入图片描述

代码展示:

#include<iostream>
using namespace std;
//确定数组的大小
const int N = 100000;
//一个存放值,一个存放下一个节点的下标
int e[N],ne[N];
//一个是下一个节点的索引,一个变量存储头节点
int idx,head;
//操作次数
int M;

void  Init()
{
	//零个节点的情况下我们的head等于-1,表示还没有任何节点
    head=-1;
    //idx定义为0,表示下一个节点的下标是0
    idx=0;
}
//在头部插插入节点
void PushFront(int x)
{
	//更新新节点存储的值
    e[idx]=x;
    //新节点的下一个节点是原来的头结点
    ne[idx]=head;
    //更新头结点,为idx
    head=idx;
    //更新idx
    idx++;
}
//在第k个节点的后面插入一个数据
void Insert(int k,int x)
{
	//更新存储节点值的数组
    e[idx]=x;
    //准备插入的节点的下一个节点是k节点指向的下一个节点
    ne[idx]=ne[k];
    //k节点指向的下一个节点是idx
    ne[k]=idx;
    //更新idx
    idx++;
}
//删除第k个节点的后一个节点
void Earase(int k)
{
	//第k个节点的下一个节点是第k个节点的下下个节点
    ne[k]=ne[ne[k]];
}


int main()
{
	//初始化
    Init();
    //输入操作数
    cin>>M;
    while(M--)
    {
        int x,k;
        char op;
        //根据样例写一个ifelse
        cin>>op;
        if(op=='H')
        {
            cin>>x;
            PushFront(x);
        }
        else if(op=='D')
        {
            cin>>k;
            if(!k) head=ne[head];
            Earase(k-1);
        }
        else
        {
            cin>>k>>x;
            Insert(k-1,x);
        }
    }
    //输出数据
    for(int i=head;i!=-1;i=ne[i])cout<<e[i]<<' ';
    return 0;
}

数组模拟双链表

双链表的实现和单链表类似,只不过我们需要三个数组,一个数组存储指向左边的的上一个节点的下标,一个数组存储下一个节点的下标,还有一个数组存储当前节点的值,还需要一个idx索引下一个元素。

看题!

题目在这里插入图片描述
样例
在这里插入图片描述

代码展示:

#include<iostream>
using namespace std;
const int N=100000;
int l[N],r[N],idx;
int e[N];

int m;

void Init()
{
    r[0]=1;
    l[1]=0;
    idx=2;
}
void Push_Right(int k,int x)
{
    //赋值
    e[idx]=x;
    //idx的右边是k节点的右边的节点
    r[idx]=r[k];
    //idx的左边是k
    l[idx]=k;
    //k的右边的指向的左边是idx
    l[r[k]]=idx;
    //k指向的右边是idx
    r[k]=idx;
    //idx++;
    idx++;
}

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

int main()
{
    cin>>m;
    Init();
    while(m--)
    {
        int k=0,x=0;
        string op;
        cin>>op;
        //在零的右边插入
        if(op == "L")
        {
            cin>>x;
            Push_Right(0,x);
        }
        //在1的左边插入,1代表最后一个节点,所以只需要在最后一个节点的左边插入
        else if(op == "R")
        {
            cin>>x;
            Push_Right(l[1],x);
        }
        //删除,因为idx是从2开始的,他是删除第k个节点,存值的节点是从2开始,所以删除第k个
        //实际是删除第k+1个
        else if(op == "D")
        {
            cin>>k;
            Earase(k+1);
        }
        //在第看个节点的左边插入,相当于在第k+1个节点的左边节点的右边插入一个值
        else if(op=="IL")
        {
            cin>>k>>x;
            Push_Right(l[k+1],x);
        }
        //在右边插入,相当于就是在第k+1哥节点的右边插入一个数
        else if(op=="IR")
        {
            cin>>k>>x;
            Push_Right(k+1,x);
        }
    }
    //打印,第一个节点是在0节点的右边开始,然后到1结束
    for(int i=r[0];i!=1;i=r[i])cout<<e[i]<<' ';
    cout<<endl;
    return 0;
}

数组实现栈

数组实现栈和数组实现单链表类似,甚至比单链表更简单,由于栈先进后出的性质,所以我们根本、不需要用到什么head

看题!

题目
在这里插入图片描述
样例
在这里插入图片描述

代码展示:

#include<iostream>
using namespace std;
const int N=100000;
//存储值的数组和存储下一个节点下标的数组
int e[N],ne[N];
//索引
int idx;
//操作数
int m;
void Init()
{
	//这里我们直接将idx置零
    idx=0;
}
void Push(int x)
{
    e[idx]=x;
    idx++;
}
void Pop()
{
    idx--;
}

bool Empty()
{
    return idx==0;
}
int Query()
{
    return e[idx-1];
}
int main()
{
    cin>>m;
    Init();
    while(m--)
    {
        string op;
        cin>>op;
        int x;
        if(op=="push")
        {
            cin>>x;
            Push(x);
        }
        else if(op=="pop")
        {
            Pop();
        }
        else if(op=="empty")
        {
            if(Empty())
            {
                cout<<"YES"<<endl;
            }
            else
            {
                cout<<"NO"<<endl;
            }
        }
        else if(op=="query")
        {
            cout<<Query()<<endl;
        }
    }
    return 0;
} 

数组模拟队列

数组模拟队列类似于数组模拟单链表,但是由于队列的特殊性质,先进先出,所以我们需要一个指向头的索引,当我们需要出队列的时候,时间复杂度可以达到O(1),也需要一个存储值的数组,和存储下一个节点下标的数组

看题!

**题目在这里插入图片描述
样例
在这里插入图片描述

代码展示:

#include<iostream>
using namespace std;
const int N=100000;
int head,idx,e[N],ne[N];
int tail;
int m;
void Init()
{
    head=-1;
    idx=0;
    tail=-1;
    m=0;
}

void Push(int x) {
    e[idx] = x;
    ne[idx] = -1; // 将新元素的下一个位置设置为 -1,表示末尾
    if (head == -1) 
    { 
        // 如果队列为空,将 head 和 tail 都设置为当前的 idx
        head = idx;
        tail = idx;
    } 
    else 
    {
        ne[tail] = idx; // 将当前的 tail 指向新元素的位置
        tail = idx; // 更新 tail
    }
    idx++;
}



void Pop()
{
    head=ne[head];
    if(head==-1)
    {
        tail=-1;
    }
}
bool Empty()
{
    return head==-1;
}
int Query()
{
    return e[head];
}
int main()
{
    Init();
    cin>>m;
    while(m--)
    {
        string op;
        cin>>op;
        int x;
        if(op=="push")
        {
            cin>>x;
            Push(x);
        }
        else if(op=="pop")
        {
            Pop();
        }
        else if(op=="empty")
        {
            if(Empty())
            {
                cout<<"YES"<<endl;
            }
            else
            {
                cout<<"NO"<<endl;
            }
        }
        else if(op=="query")
        {
            cout<<Query()<<endl;
        }
    }
    return 0;
}

总结

在本文中,我们深入探讨了如何使用数组来模拟基本的数据结构,包括栈、队列和链表。通过这些模拟,我们不仅加深了对这些数据结构的理解,还学会了如何利用数组的特性来实现它们。通过使用数组,我们可以更好地理解数据结构的底层原理,并且在实际编程中更灵活地应用这些概念。无论是在算法竞赛中还是在实际项目中,对数组模拟数据结构的掌握都将为我们带来更多的解决方案和优化思路。希望本文能够帮助你更深入地理解数组和数据结构,并在你的编程旅程中有所启发!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

挑战一周完成Vue3实战项目硅谷甄选Day1:项目初始化、项目配置、项目集成

一、项目初始化 node v16.4.0以上&#xff08;查看node版本 : node -v&#xff09; pnpm 8.0.0&#xff08;npm i -g pnpm8.0.0&#xff09; 在想创建的位置新建文件夹自己命名 在此文件夹下cmd:pnpm create vite 选择如下配置 Project name&#xff08;项目名称&#xff0…

Java设计模式 _创建者模式_工厂模式(普通工厂和抽象工厂)

一、工厂模式 属于Java设计模式创建者模式的一种。在创建对象时不会对客户端暴露创建逻辑&#xff0c;并且是通过使用一个共同的接口来指向新创建的对象。 二、代码示例 场景&#xff1a;花店有不同的花&#xff0c;通过工厂模式来获取花。 1、普通工厂模式 逻辑步骤&#…

Spring - 5 ( 8000 字 Spring 入门级教程 )

一&#xff1a;Spring IoC&DI 1.1 方法注解 Bean 类注解是添加到某个类上的&#xff0c; 但是存在两个问题: 使用外部包里的类, 没办法添加类注解⼀个类, 需要多个对象, ⽐如多个数据源 这种场景, 我们就需要使用方法注解 Bean 我们先来看方法注解如何使用: public c…

AI-数学-高中-42导数的概念与意义

原作者视频&#xff1a;【导数】【一数辞典】1导数的概念与意义_哔哩哔哩_bilibili .a是加速度&#xff1b;

OpenAI 笔记:获取embedding

1 输入openai的api key from openai import OpenAIclient OpenAI(api_key**) 2 举例 response client.embeddings.create(input"Hello",model"text-embedding-3-small" )print(response.data[0].embedding) 默认情况下&#xff0c;text-embedding-3-s…

配置Linux【虚拟机】与 windows【宿主机】网络互通 (面向小白,简单操作)

1. 启动虚拟机&#xff0c;运行Linux系统 这里我使用 VMware Workstation Pro 来运行Linux系统&#xff08;cent-os7&#xff09;2. 鼠标右键打开终端 3. 输入 cd /etc/sysconfig/network-scripts , 然后输入ls &#xff0c;查看当前目录下的网卡 一般来说&#xff0c;虚拟机的…

计算机网络基础认识

本篇文章是我在B站上看到关于计算机网络的介绍视频收到的启发。本篇文章的内容来自【网络】半小时看懂<计算机网络>_哔哩哔哩_bilibili 一、物理层 从常理来说&#xff0c;进行连个设备之间的通讯&#xff0c;首先最容易想到的就是使用一根线连接两个设备进行通讯。但是…

Docker的数据管理、网络通信和dockerfile

目录 一、Docker的数据管理 1. 数据卷 1.1 数据卷定义 1.2 数据卷配置 2. 数据卷容器 2.1 创建数据卷容器 2.2 使用--volume-from来挂载test1 二、端口映射 三、容器互联 1. 创建容器互联 ​编辑2. 进入test2测试&#xff08;ping 容器名/别名&#xff09; 四、Dock…

【弱监督点云分割】All Points Matter:用于弱监督三维分割的熵细化分布对齐

All Points Matter: Entropy-Regularized Distribution Alignment for Weakly-supervised 3D Segmentation 摘要&#xff1a; 伪标签被广泛应用于弱监督三维分割任务中&#xff0c;在这种任务中&#xff0c;只有稀疏的地面真实标签可供学习使用。现有方法通常依赖经验标签选择…

用立创EDA实现一个小项目

项目介绍 名称&#xff1a;蓝牙音响 功能&#xff1a;按键切换 蓝牙控制 语音控制 项目流程 市场调研产品立项----老板--经理硬件&#xff08;外观、尺寸、大小、使用环境&#xff09;软件&#xff08;代码开发环节&#xff09;产品测试 以管理员身份运行 新建文件夹&…

Python学习从0开始——项目一day02数据库连接

Python学习从0开始——项目一day02数据库连接 一、在线云数据库二、测试数据库连接三、数据库驱动介绍四、SQL执行4.1插入测试数据4.2安装数据库连接模块4.3测试SQL语句执行4.4执行SQL的固定步骤及示例 一、在线云数据库 找了一个在线数据库&#xff0c;需要邮箱注册&#xff…

使用Docker搭建Redis主从集群

文章目录 ☃️前言☃️搭建❄️❄️架构❄️❄️实例说明❄️❄️搭建第一个服务器上的两个实例❄️❄️搭建第二个服务器上的一个实例 ☃️开启主从❄️❄️改配置❄️❄️重启从节点 ☃️验证 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 …

《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制婴儿性别比例饼图

在MATLAB 中可以使用 pie 函数来创建饼图。饼图是一种展示不同部分占总体的相对比例的图表。 本示例从“婴儿出生数据.csv”文件读取婴儿出生数据&#xff0c;然后计算男性和女性婴儿的数量&#xff0c;使用MATLAB绘制饼图。 配套图书链接&#xff1a;https://item.jd.com…

【ruoyi-vue】axios的封装理解和基本使用

axios的配置 ruoyi的前端对axios进行了封装&#xff0c;让我们发get请求或者是post请求更加方便了。 ruoyi对axios的封装在下面文件中&#xff1a;打开文件&#xff0c;可以看到它有三个显眼的方法&#xff0c;分别是request拦截器、response拦截器和通用下载方法。ruoYi接口地…

MySQL主从的应用

说明&#xff1a;本文介绍MySQL主从在实际中的应用。主从搭建和问题参考下面两篇文章&#xff1a; MySQL主从结构搭建 搭建MySQL主从结构时的问题 数据迁移 当我们搭建完MySQL主从&#xff0c;第一步当然是把历史数据导入到主从结构中。有以下两种方式&#xff1a; 开启主从…

Linux 网络操作命令Telnet

Telnet 尽管 Telnet 已经逐渐被更安全的 SSH 协议所取代&#xff0c;但在某些特定场景下&#xff0c;如对旧系统的维护或教育目的&#xff0c;Telnet 仍然有其使用价值。本文将介绍如何在 Linux 系统中安装 Telnet 客户端&#xff0c;以及如何使用它进行远程登录。 用户使用 t…

什么是DTU和串口服务器的区别

在工业物联网的快速发展中&#xff0c;数据传输单元&#xff08;DTU&#xff09;和串口服务器作为两种关键设备&#xff0c;各自扮演着重要的角色。对于传统行业来说&#xff0c;了解它们的基本概念和区别&#xff0c;有助于更好地选择和应用这些技术&#xff0c;提升生产效率和…

Rust基本数据类型-切片

一、切片是什么&#xff0c;怎么用 1、切片是什么 切片并不是 Rust 独有的概念&#xff0c;在 Go 语言中就非常流行&#xff0c;它允许你引用集合中部分连续的元素序列&#xff0c;而不是引用整个集合。 对于字符串而言&#xff0c;切片就是对 String 类型中某一部分的引用&…

基于单片机的空气质量检测系统设计

摘要:随着社会经济的不断发展,人们的生活水平日益提高,健康与养生成为了全民关注的热点话题,空气质量地不断下降也引起了社会的广泛关注,如何了解家居内空气质量的情况也成了亟需解决的问题。在此背景下,本文针对室内空气的质量问题设计了基于单片机的空气质量检测系统,…

Mysql个人总结

前言 又来水字数啦&#xff0c;这次主要讲一下MySQL的常用概念&#xff0c;难点的就必须上项目讲解了&#xff0c;而且比较基础面试基本都会问一些&#xff0c;用的话&#xff0c;不少优化都从这里入手 操作数据库 1、创建数据库 CREATE DATABASE [IF NOT EXISTS] 数据库名;…