链表初解(二)——双链表的创建、删除、插入

2024-08-21 15:18

本文主要是介绍链表初解(二)——双链表的创建、删除、插入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面是基本的双链表操作,由于双链表有两个方向,所以在删除和插入节点时,可以节省一个指针,只用一个链表上的指针和一个待操作的指针即可完成插入和删除;同时也要注意在编写双链表时对情况的判断要仔细,否则很容易出错~

#include<iostream>
using namespace std;typedef struct student
{int data;struct student *next;struct student *pre;
}dnode;//建立双链表
dnode *create()
{dnode *head, *p, *s;int x;head = (dnode *)malloc(sizeof(dnode));p = head;cout<<"\nInput the data : ";while(1){if(scanf("%d", &x) != EOF && x != 0){s = (dnode *)malloc(sizeof(dnode));s->data = x;p->next = s;s->pre = p;p = s;}else break;}head = head->next;head->pre = NULL;p->next = NULL;return head;
}//双链表删除节点
dnode *del(dnode *head, int num)
{dnode *p1;p1 = head;while(num != p1->data && p1->next != NULL)p1 = p1->next;if(num == p1->data){if(head == p1){head = head->next;head->pre = NULL;}/*此处的处理与单链表不同,因为双链表有两个方向,所以在定义时仅定义一个指针,这使得当出现删除链表尾部时,由于NULL没有前驱,导致无法连接,所以要分开讨论。*/else if(p1->next == NULL) p1->pre->next = NULL;else{//p1为最后一个节点,如没有上一个分支,则第二个语句会出错。p1->pre->next = p1->next;p1->next->pre = p1->pre;}free(p1);	//释放}else cout<<"There is no %d "<<num;return head;
}//双链表插入节点
dnode *insert(dnode *head, int num)
{dnode *p0, *p1;p1 = head;p0 = (dnode *)malloc(sizeof(dnode));p0->data = num;while(num > p1->data && p1->next != NULL)p1 = p1->next;if(num <= p1->data){if(head == p1){p0->next = p1;p1->pre = p0;head = p0;}else{p1->pre->next = p0;p0->pre = p1->pre;p0->next = p1;p1->pre = p0;}}else{//插入尾部~p1->next = p0;p0->next = NULL;p0->pre = p1;}return head;
}//计算表长
int length(dnode *head)
{int n = 0;while(head != NULL){head = head->next;n++;}return n;
}
//打印双链表
void print(dnode *head)
{int n = length(head);cout<<"Output the DoubleList ("<<n<<" records~) : ";while(head != NULL){if(head->next == NULL) cout<<head->data<<endl;else cout<<head->data<<"<->";head = head->next;}
}
//排序函数同单链表,此处省略了~,默认输入为递增哈~
int main()
{dnode *head;//创建head = create();print(head);//删除int numD;cout<<"\nDelete : ";cin>>numD;print(del(head, numD));//插入int numS;cout<<"\nInsert : ";cin>>numS;print(insert(head, numS));return 0;
}


Ps:仅供参考~~

 

这篇关于链表初解(二)——双链表的创建、删除、插入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093529

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

mybatisplus的逻辑删除过程

《mybatisplus的逻辑删除过程》:本文主要介绍mybatisplus的逻辑删除过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录myBATisplus的逻辑删除1、在配置文件中添加逻辑删除的字段2、在实体类上加上@TableLogic3、业务层正常删除即

MySQL的触发器全解析(创建、查看触发器)

《MySQL的触发器全解析(创建、查看触发器)》MySQL触发器是与表关联的存储程序,当INSERT/UPDATE/DELETE事件发生时自动执行,用于维护数据一致性、日志记录和校验,优点包括自动执行... 目录触发器的概念:创建触www.chinasem.cn发器:查看触发器:查看当前数据库的所有触发器的定

MybatisPlus中removeById删除数据库未变解决方案

《MybatisPlus中removeById删除数据库未变解决方案》MyBatisPlus中,removeById需实体类标注@TableId注解以识别数据库主键,若字段名不一致,应通过value属... 目录MyBATisPlus中removeBypythonId删除数据库未变removeById(Se

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录

MySQL逻辑删除与唯一索引冲突解决方案

《MySQL逻辑删除与唯一索引冲突解决方案》本文探讨MySQL逻辑删除与唯一索引冲突问题,提出四种解决方案:复合索引+时间戳、修改唯一字段、历史表、业务层校验,推荐方案1和方案3,适用于不同场景,感兴... 目录问题背景问题复现解决方案解决方案1.复合唯一索引 + 时间戳删除字段解决方案2:删除后修改唯一字