数据结构03 链表的基本操作【C++数组模拟实现】

news2024/10/5 19:15:00

前言:本节内容主要了解链表的基本概念及特点,以及能够通过数组模拟学会链表的几种基本操作,下一节我们将通过STL模板完成链表操作,可以通过专栏进入查看下一节哦~

目录

单链表及其特点

完整链表构成

完整链表简述

创建单链表

定义节点存储结构

尾插法插入元素

遍历并显示链表内容

头插法插入元素

向链表中插入元素

删除元素

查找元素

链表基本操作完整代码


单链表及其特点

链表的种类较多,这里我们主要讲解最常见的带头结点的单链表。

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。


如图所示,链表中每个数据的存储都由以下两部分组成:

1.数据元素本身,其所在的区域称为数据域;

2.指向直接后继元素的指针,所在的区域称为指针域;

完整链表构成

1.头结点:头节点是一个不存储任何数据的结点,是为了方便找到链表位置。

2.首元结点:它是链表中称第一个存有数据的节点为首元结点,称呼没有实际意义。

3.其他结点:链表中其他的结点。

完整链表简述

注意:链表中有头结点时,头指针指向头结点;反之,若链表中没有头结点,则头指针指向首元结点。

简单的来说,链表就像一环扣一环的链子一样,当你想插入删除元素的时候,只需要找到你要插入或者删除的位置,然后解开该位置两边的环,然后将新的环连接上即可。

由于链表的特殊结构,决定了它拥有一个数组所没有的优势,那就是进行插入删除操作的时候,不需要移动元素。但是缺点就是查找元素需要从头结点开始一个一个往后找。

创建单链表

单链表在创建的时候需要先声明结点,方可创建链表,即向链表中插入元素。插入元素时,又可分为头插法和尾插法。头插法和尾插法的区别后面会通过结果展示出来。

头插法:在头结点之后插入数据,其特点是读入的数据顺序与线性表的逻辑顺序正好相反,可用来实现倒序输出一个元素序列。

尾插法:将每次插入的新结点放在链表的尾部。   

定义节点存储结构

struct Node
{
    int data;    //保存节点中存储的数据
    Node *next; //指向下一结点
};

尾插法插入元素

void Wcreate(Node *l,int n) //尾插法向链表中插入n个数字
{
    Node *p,*r; //p用来指向新生成的结点。r始终指向l的终端结点。
    r=l;     //r指向了头节点,此时的头节点也是终端节点
    int k;
    for(int i=0;i<n;i++) {
        cin>>k;
        p=new Node; //为结点分配空间
        p->data=k;  //将数值存入新结点
        r->next=p;   //接受新的结点
        r=p;  //r指向终端结点
    }
    r->next=NULL; //l的终端结点指针域为NULL,l建立完成
}

遍历并显示链表内容

void show(Node *l)
{
    Node *p;
    p=l->next;
    while(p!=NULL)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

头插法插入元素

void Tcreate(Node *l,int n) //头插法向链表中插入n个数字
{
    Node *p; //p用来指向新生成的结点
    l->next=NULL;
    int k;
    for(int i=0;i<n;i++) {
        cin>>k;
        p=new Node; //为结点分配空间
        p->data=k;  //将数值存入新结点
        p->next=l->next;  //将l指向的地址赋值给p;
        l->next=p; //头指针的指针域next指向p结点,使得p成为开始结点。
    }
}

向链表中插入元素

void insert(Node *l,int k,int e)//在第k个位置后插入元素e;
{
    Node *p,*r;
    r=l;
    if(r->next==NULL) cout<<"链表为空";
    for(int i=0;i<k;i++) //找到第k个位置之前的那个位置
        r=r->next;
    p=new Node; //为新结点申请空间
    p->data=e;
    p->next=r->next;
    r->next=p;
}

删除元素

void Delete(Node *l,int x) //删除第一个值为x的数。
{
    Node *r,*pre;
    pre=l; //记录前驱结点,防止断链
    r=l->next;
    while(r->data!=x)
    {
     pre=r;  //记录该结点前一个结点
     r=r->next;
     }
    pre->next=r->next; //将其前驱next指向其后继,实现删除
}

查找元素

//查找值为X的数是否存在,在则输出第一次出现的位置。
void Search(Node *l,int x) {
    int k=1;  //记录位置
    Node *p;
    p=l->next;
    while(p->data!=x&&p->next!=NULL) {
        p=p->next;
        k++;
    }
    if(p->data!=x) cout<<"未找到"<<endl;
    else cout<<"是第"<<k<<"个数字"<<endl;
}

链表基本操作完整代码

#include<iostream>
using namespace std;
struct Node
{
    int data;    //保存结点中存储的数据
    Node *next; //指向下一结点
};

void Wcreate(Node *l,int n) //尾插法向链表中插入n个数字
{
    Node *p,*r; //p用来指向新生成的节点。r始终指向l的终端节点。
    r=l;     //r指向了头节点,此时的头节点也是终端节点
    int k;
    for(int i=0;i<n;i++) {
        cin>>k;
        p=new Node; //为节点分配空间
        p->data=k;  //将数值存入新节点
        r->next=p;   //接受新的节点
        r=p;  //r指向终端节点
    }
    r->next=NULL; //l的终端节点指针域为NULL,l建立完成
}

void Tcreate(Node *l,int n) //头插法向链表中插入n个数字
{
    Node *p; //p用来指向新生成的结点
    l->next=NULL;
    int k;
    for(int i=0;i<n;i++) {
        cin>>k;
        p=new Node; //为结点分配空间
        p->data=k;  //将数值存入新结点
        p->next=l->next;  //将l指向的地址赋值给p;
        l->next=p; //头指针的指针域next指向p结点,使得p成为开始结点。
    }
}

void show(Node *l)
{
    Node *p;
    p=l->next;
    while(p!=NULL)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

void Search(Node *l,int x) //查找第一个值为X的数是否存在。
{
    int k=1;  //记录位置
    Node *p;
    p=l->next;
    while(p->data!=x&&p->next!=NULL){
        p=p->next;
        k++;
    }
    if(p->data!=x) cout<<"未找到"<<endl;
    else cout<<"是第"<<k<<"个数字"<<endl;
}

int main()
{
    Node *L; //数据第一个数字位置是0
    L=new Node;
    L->next=NULL;
    int n,x,m;
    cin>>n;
    Wcreate(L,n);
    cout<<"尾插法插入结果:";
    show(L);
    /*
    Tcreate(L,n);
    cout<<"头插法插入结果:";
    show(L);
    cout<<"\n请输入插入的位置及元素值:"<<endl;
    cin>>m>>x;
    Insert(L,m,x);
    show(L);
    cout<<"\n请输入要删除的数值:"<<endl;
    cin>>x;
    Delete(L,x);
    show(L);
    */
    cout<<"\n请输入要查找的数值:"<<endl;
    cin>>x;
    Search(L,x);
    return 0;
}

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

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

相关文章

MySQL自增主键踩坑记录

对于MySQL的自增主键&#xff0c;本文记录、整理下在工作中实际遇到的问题。 下面示例均基于MySQL 8.0 修改列的类型后&#xff0c;自增属性消失 CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,email VARCHAR(100) NOT NULL );上面的…

计算机监控软件有哪些?10款常年霸榜的计算机监控软件

计算机监控软件是企业管理和保护信息安全的重要工具&#xff0c;它们帮助企业管理者监督员工的计算机使用行为&#xff0c;确保工作效率、数据安全以及合规性。在众多监控软件中&#xff0c;有些产品因其卓越的功能、易用性、安全性以及持续获得的良好市场反馈而常年占据行业领…

什么是指令微调(LLM)

经过大规模数据预训练后的语言模型已经具备较强的模型能力&#xff0c;能够编码丰富的世界知识&#xff0c;但是由于预训练任务形式所限&#xff0c;这些模型更擅长于文本补全&#xff0c;并不适合直接解决具体的任务。 指令微调是相对“预训练”来讲的&#xff0c;预训练的时…

spring mvc实现一个自定义Formatter请求参数格式化

使用场景 在Spring Boot应用中&#xff0c;Formatter接口用于自定义数据的格式化&#xff0c;比如将日期对象格式化为字符串&#xff0c;或者将字符串解析回日期对象。这在处理HTTP请求和响应时特别有用&#xff0c;尤其是在展示给用户或从用户接收特定格式的数据时。下面通过…

集合,Collection接口

可动态保存任意多个对象&#xff0c;使用比较方便 提供了一系列方便操作对象的方法&#xff1a;add&#xff0c;remove&#xff0c;set&#xff0c;get等 使用集合添加删除新元素&#xff0c;代码简洁明了 单列集合 多列集合 Collection接口 常用方法 List list new Arra…

【原创图解 算法leetcode 146】实现一个LRU缓存淘汰策略策略的数据结构

1 概念 LRU是Least Recently Used的缩写&#xff0c;即最近最少使用&#xff0c;是一种常见的缓存淘汰算法。 其核心思想为&#xff1a;当内存达到上限时&#xff0c;淘汰最久未被访问的缓存。 2 LeetCode LeetCode: 146. LRU缓存 3 实现 通过上面LRU的淘汰策略可知&#…

北京市大兴区餐饮行业协会成立暨职业技能竞赛总结大会成功举办

2024年6月27日下午&#xff0c;北京市大兴区营商服务中心B1层报告厅迎来了北京市大兴区餐饮行业协会成立仪式暨2024年北京市大兴区餐饮行业职工职业技能竞赛总结大会。此次活动不仅标志着大兴区餐饮行业协会的正式成立&#xff0c;也对在2024年大兴区餐饮行业职工职业技能竞赛中…

Python自动化测试:web自动化测试——selenium API、unittest框架的使用

web自动化测试2 1. 设计用例的方法——selenium API1.1 基本元素定位1&#xff09;定位单个唯一元素2&#xff09;定位一组元素3&#xff09;定位多窗口/多框架4&#xff09;定位连续层级5&#xff09;定位下拉框6&#xff09;定位div框 1.2 基本操作1.3 等待1.4 浏览器操作1.5…

SpringBoot整合Quartz实现动态定时任务

目录 1、Quartz简介1.1 Quartz的三大核心组件1.2 CronTrigger配置格式 2、SpringBoot整合Quartz框架2.1 创建项目2.2 实现定时任务 1、Quartz简介 Quartz是一个开源的任务调度服务&#xff0c;它可以独立使用&#xff0c;也可与其它的Java EE&#xff0c;Java SE应用整合使用。…

Python数据分析案例48——二手房价格影响因素分析

案例背景 房价影响因素也是人们一直关注的问题&#xff0c;本次案例也适合各种学科的同学&#xff0c;无论你是经济管理类还是数学统计&#xff0c;还是电商物流类&#xff0c;都可以使用回归分析。通过数据分析回归分析分组聚合可视化等方法进行研究房价影响因素。 数据介绍 …

2024下半年必追国漫片单,谁将问鼎巅峰?

随着2024年上半年的落幕&#xff0c;国漫市场再度迎来了百花齐放的盛况。从经典续作到全新IP&#xff0c;从玄幻到科幻&#xff0c;每一部作品都以其独特的魅力吸引着观众的目光。本期为大家盘点下半年值得一看的国漫佳作&#xff0c;大胆预测&#xff0c;谁将成为这场神仙打架…

Grafana-11.0.0 在线部署教程

Grafana-11.0.0 在线部署教程 环境&#xff1a; 操作系统&#xff1a; ubuntugrafana版本&#xff1a; 11.0.0 &#xff08;建议不要按照最新版&#xff09;grafana要求的系统配置不高&#xff0c;建议直接部署在监控服务器上&#xff0c;比如zabbix服务器、prometheus服务器…

【Stable Diffusion】创意与科技的完美结合:AI绘画副业让美术老师月入2w+

前言 艺术与科技一直以来都是两个看似独立的领域&#xff0c;但如今&#xff0c;随着人工智能的发展&#xff0c;这两个领域正迎来一次前所未有的融合。在这个数字化时代&#xff0c;AI绘画成为了一项引人注目的副业&#xff0c;为美术老师们带来了新的机遇和收入。 儿童画 …

实验场:在几分钟内使用 Elasticsearch 进行 RAG 应用程序实验

作者&#xff1a;来自 Elastic Joe McElroy, Serena Chou 什么是 Playground&#xff08;实验场&#xff09;&#xff1f; 我们很高兴发布我们的 Playground 体验 —- 一个低代码界面&#xff0c;开发人员可以在几分钟内使用自己的私人数据探索他们选择的 LLM。 在对对话式搜…

“实时数据大屏2k、4k、8k”这样做【高级前端必备技能之一】

&#x1f525;废话不多先上效果图 &#x1f525;划重点 新手程序员需要注意以下几点&#xff1a; 我们需要进行充分的技术调研&#xff0c;进行技术选型产品&#xff0c;UI&#xff0c;再三确认效果图是否确定&#xff0c;避免后续出现返工的情况 不能拿到效果图之后&#x…

事务的概念-事务的概念、事务的定义(BEGIN TRANSACTION、COMMIT、ROLLBACK)

数据库系统中的事务&#xff0c;是保证系统在发生故障后或存在并发操作的情况下&#xff0c;数据库中的数据与企业业务结果相一致 一、事务的概念 在许多数据库应用系统中&#xff0c;数据库用来存储现实世界中一些企业的状态信息或其管理的数据 1、概念一 &#xff08;1&a…

《昇思25天学习打卡营第3天|张量 Tensor》

文章目录 前言&#xff1a;今日所学&#xff1a;1. 创建张量2. 张量的属性3.张量索引与运算4. NumPy与Tensor的转换5. 稀疏张量 前言&#xff1a; 张量&#xff1f;张亮&#xff1f;张量是什么&#xff1f; 张量是一个可以用来表示在一些矢量、标量和其他张量之间的线性关系的…

博途TIA Portal「集成自动化软件」下载安装,TIA Portal 灵活多变的编程环境

在编程领域&#xff0c;博途TIA Portal以其卓越的编程工具和灵活多变的编程环境&#xff0c;为众多用户提供了前所未有的便利。这款软件不仅支持多种编程语言&#xff0c;如梯形图&#xff08;Ladder Diagram&#xff09;、功能块图&#xff08;Function Block Diagram&#xf…

2024夏促steam商店加载失败、steam无法加载活动怎么办

今年的夏季促销活动终于开始了&#xff0c;一般夏季促销大多是去年和今年的热门游戏&#xff0c;不过也会有不少经典游戏参与活动&#xff0c;都是较低的价格出售。因为最近高考结束&#xff0c;考虑到会有不少新玩家前来入手游戏&#xff0c;为了让大家能顺利找到喜欢的游戏&a…

使用 Elastic ELSER 和 Llama3 的 RAG(使用 Langchain)

在之前的文章 “使用 Llama 3 开源和 Elastic 构建 RAG”&#xff0c;我们讲到了如何使用 Liama3 来结合 Elastic ELSER 来进行 RAG。在今天的文章里&#xff0c;我们来详细使用一个 notebook 来展示如何在本地 Elasticsearch 部署中进行实现。 此交互式 notebook 使用 Langch…