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

前言:本节内容主要了解链表的基本概念及特点,以及能够通过数组模拟学会链表的几种基本操作,下一节我们将通过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;
}

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

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

相关文章

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

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

『SD』AI绘画,不会写提示词怎么办?

提示词 有没有想过&#xff0c;为什么你用 SD 生成的猫是长这样的。 而其他人可以生成这样的猫。 虽然生成的都是猫&#xff0c;但猫与猫之间还是有差距的。 如果你的提示词只是“cat”&#xff0c;那大概率就会出现本文第一张图的那个效果。而如果你加上一些形容词&#xff…

【涵子来信】——社交宝典:克服你心中的内向,世界总有缺陷

内向&#xff0c;你是内向的吗&#xff1f;想必每个人不同&#xff0c;面对的情形也是不同的。 暑假是一个很好的机会&#xff0c;我是可以去多社交社交。但是&#xff0c;面对着CSDN上这么多技术人er&#xff0c;那么&#xff0c;我的宝典&#xff0c;对于大家&#xff0c;有…

【刷题】初步认识深搜(DFS)

送给大家一句话&#xff1a; 拥有希望的人&#xff0c;和漫天的星星一样&#xff0c;是永远不会孤独的。 -- 《星游记》 初步认识深搜&#xff08;DFS&#xff09; dfs算法二叉树中的深搜Leetcode 129. 求根节点到叶节点数字之和题目描述算法思路 Leetcode 814. 二叉树剪枝题…

poi-tl 生成 word 文件(插入文字、图片、表格、图表)

文章说明 本篇文章主要通过代码案例的方式&#xff0c;展示 poi-tl 生成 docx 文件的一些常用操作&#xff0c;主要涵盖以下内容 &#xff1a; 插入文本字符&#xff08;含样式、超链接&#xff09;插入图片插入表格引入标签&#xff08;通过可选文字的方式&#xff0c;这种方…

英国牛津大学博士后职位—统计学

牛津大学&#xff08;University of Oxford&#xff09;&#xff0c;简称“牛津”&#xff08;Oxford&#xff09;&#xff0c;位于英国牛津&#xff0c;是一所公立研究型大学&#xff0c;采用传统学院制。是罗素大学集团成员&#xff0c;被誉为“金三角名校”、“G5超级精英大…

python 第6册 辅助excel 002 批量创建非空白的 Excel 文件

---用教授的方式学习 此案例主要通过使用 while 循环以及 openpyxl. load_workbook()方法和 Workbook 的 save()方法&#xff0c;从而实现在当前目录中根据已经存在的Excel 文件批量创建多个非空白的Excel 文件。当运行此案例的Python 代码&#xff08;A002.py 文件&#xff0…

论文阅读_优化RAG系统的检索

英文名称: The Power of Noise: Redefining Retrieval for RAG Systems 中文名称: 噪声的力量&#xff1a;重新定义RAG系统的检索 链接: https://arxiv.org/pdf/2401.14887.pdf 作者: Florin Cuconasu, Giovanni Trappolini, Federico Siciliano, Simone Filice, Cesare Campag…

MyBatis Plus条件构造器使用

1Wrapper&#xff1a; 条件构造抽象类&#xff0c;最顶端父类 1.1 AbstractWrapper&#xff1a; 用于查询条件封装&#xff0c;生成 sql 的 where 条件 1.2 QueryWrapper&#xff1a; Entity 对象封装操作类&#xff0c;不是用lambda语法 1.3 UpdateWrapper&#xff1a; Update…

[Go 微服务] go-micro + consul 的使用

文章目录 1.go-micro 介绍2.go-micro 的主要功能3.go-micro 安装4.go-micro 的使用4.1 创建服务端4.2 配置服务端 consul4.3 生成客户端 5.goodsinfo 服务5.1 服务端开发5.2 客户端开发 1.go-micro 介绍 Go Micro是一个简化分布式开发 的微服务生态系统&#xff0c;该系统为开…

java热部署idea插件「jrebel安装教程」

告别漫长的项目重启等待&#xff0c;让开发像写诗一样流畅~ jrebel安装包下载 jrebel版本需要下比较老的版本&#xff0c;我用的是22.4.1的版本&#xff08;如果不差钱&#xff0c;可以支持一下正版&#xff0c;直接选择最新的版本即可&#xff09; 下载地址&#xff1a;传送门…

Python逻辑控制语句 之 判断语句--if else结构

1.if else 的介绍 if else &#xff1a;如果 ... 否则 .... 2.if else 的语法 if 判断条件: 判断条件成立&#xff0c;执行的代码 else: 判断条件不成立&#xff0c;执行的代码 &#xff08;1&#xff09;else 是关键字, 后⾯需要 冒号 &#xff08;2&#xff09;存在冒号…

链表-求链表中环的入口结点(easy)

目录 一、问题描述 二、解题思路 三、代码实现 四、刷题链接 一、问题描述 二、解题思路 本题基本思路&#xff1a; 1.设置一个hashSet来存储已经访问过的链表结点地址&#xff0c;注意不要直接存储链表内元素&#xff0c;因为链表内元素可能存在重复的&#xff0c;地址是不…

uniapp uniCloud云开发

uniCloud概述 uniCloud 是 DCloud 联合阿里云、腾讯云、支付宝云&#xff0c;为开发者提供的基于 serverless 模式和 js 编程的云开发平台。 uniCloud 的 web控制台地址&#xff1a;https://unicloud.dcloud.net.cn 文档&#xff1a;https://doc.dcloud.net.cn/uniCloud/ un…

【高考志愿】集成电路科学与工程

目录 一、专业概述 二、课程设置 三、就业前景 四、适合人群 五、院校推荐 六、集成电路科学与工程专业排名 一、专业概述 集成电路科学与工程&#xff0c;这一新兴且引人注目的交叉学科&#xff0c;正在逐渐崭露头角。它集合了电子工程、计算机科学、材料科学等多个领域的…

Kotlin中对空的很多处理

代码图片直观效果 逐行解释Kotlin中对空的各种情况的使用 private fun testNull() {val flag 1var name: String? nullvar user: User? // 有警告, 因为下面的赋值可以和这一行定义合并var zhangUser: User? User()var wangUser: User User() // 提示Explicitly given t…

Unity 字体创建时候容易导致字体文件不正确的一种情况

上面得到了两种字体格式&#xff0c;一种是TextMeshPro的&#xff0c;另一种是Unity UI系统中默认使用的字体资源。其原因是创建的位置不同导致的。 1.下面是TextMeshPro字体创建的位置 2&#xff1a;下面是Unity UI系统中默认使用的字体资源

Java学习【IO流:深入理解与应用(上)】

Java学习【IO流&#xff1a;深入理解与应用&#xff08;上&#xff09;】 &#x1f343;1.IO流体系结构&#x1f343;2.FileOutputStream&#x1f341;2.1FileOutputStream写数据的三种方式&#x1f341;2.2换行和续写 &#x1f343;3.FileInputStream&#x1f341;3.1每次读取…

pbootcms后台获取前端表单留言页面url

pbootcms在线留言表单&#xff0c;用户在网页前端提交表单成功后&#xff0c;在网站后台如何获取表单留言页面的url这个参数呢&#xff1f;下面举例说明&#xff1a;首先&#xff0c;我们在PBootcms后台对应的表单&#xff0c;添加需要记录的表单字段&#xff0c;例如 添加liuy…

微服务-网关Gateway

个人对于网关路由的理解&#xff1a; 网关就相当于是一个项目里面的保安&#xff0c;主要作用就是做一个限制项。&#xff08;zuul和gateway两个不同的网关&#xff09; 在路由中进行配置过滤器 过滤器工厂&#xff1a;对请求或响应进行加工 其中filters&#xff1a;过滤器配置…