【数据结构】 双链表的基本操作 (C语言版)

目录

一、双链表

1、双链表的定义:

2、双链表表的优缺点: 

二、双链表的基本操作算法(C语言)

 1、宏定义

 2、创建结构体

3、双链表的初始化 

4、双链表表插入

5、双链表的查找

6、双链表的取值

7、求双链表长度

8、双链表的删除

9、双链表的清空

10、双链表的销毁

11、输出链表元素

三、双链表的全部代码(C语言)

四、运行结果


一、双链表

1、双链表的定义:

双链表也叫双向链表,是一种链表数据结构。它的每个数据结点包含两个指针,一个指向前一个结点,另一个指向后一个结点。这意味着从双向链表的任何节点都可以方便地访问其前驱或后继节点。通常,我们构造双向循环链表,它的特点是尾节点的指针域指向头结点,整个链表形成一个环。

 

2、双链表表的优缺点: 

双链表的优点:

  1. 可以方便地访问前驱和后继节点,既可以向前也可以向后遍历链表。
  2. 在某些情况下,双链表比单链表更节省空间,因为它不需要额外的指针来存储前驱和后继节点的信息。

双链表的缺点:

  1. 插入和删除节点相对复杂,需要更多的时间来调整指针。
  2. 双链表需要更多的存储空间,因为每个节点都需要额外的指针来存储前驱和后继节点的信息。

二、双链表的基本操作算法(C语言)

 1、宏定义
#define OK 1
#define ERROR 0typedef char ElemType;
typedef int Status;
 2、创建结构体
typedef struct DuLNode {ElemType data;struct DuLNode *prior;struct DuLNode *next;
} DuLNode, *DuLinkList;
3、双链表的初始化 
//双链表初始化
Status DInitList(DuLinkList &head) {head = new DuLNode;head->prior = NULL;head->next = NULL;return OK;
}
4、双链表表插入
//插入
Status DListInsert(DuLinkList &head, int i, ElemType e) {DuLinkList p = head;int j = 0;while (p && (j < i - 1)) {p = p->next;++j;}if (!p || j > i - 1) {return ERROR;}DuLNode *s = new DuLNode;s->data = e;s->next = p->next;if(p->next != NULL){p->next->prior = s;	}p->next = s;s->prior = p;return OK;
}
5、双链表的查找

//查找
int DLocateLinkListElem(DuLinkList head, ElemType e) {DuLinkList p = head->next;int j = 1;while (p && (p->data != e)) {p = p->next;j++;}if (p == NULL) { return 0;}return j;
}
6、双链表的取值
//取值
Status DGetLinkList(DuLinkList head, int i, ElemType &e) {DuLinkList p = head->next;int j = 1;while (p && j < i) {p = p->next;++j;}if (p == NULL) {return ERROR;}e = p->data;return OK;
}
7、求双链表长度
//求双链表长度
Status DGetLinkListLength(DuLinkList head) {DuLinkList p = head->next;int length = 0;while (p!=NULL) {            //单链表不为空表时length++;p = p->next;}return length;
}
8、双链表的删除
//删除
Status DListDelete(DuLinkList &head, int i, ElemType &e) {DuLinkList p = head;int j = 0;while (p && j < i - 1) {p = p->next;j++;}if (!p) {return ERROR;}DuLinkList q = p->next;e = q->data;p->next = q->next;if(q->next != NULL){q->next->prior=p;}delete q;return OK;
}
9、双链表的清空
//清空
Status DClearLinkList(DuLinkList &head) {DuLinkList p = head->next;DuLinkList q;while (p) {q = p;p = p->next;delete q;}head->next = NULL;return OK;
}
10、双链表的销毁
//销毁
Status DestoryDLinkList(DuLinkList &head) {DuLinkList p;while (head) {p = head;head = head->next;delete p;}return OK;
}
11、输出链表元素
//输出链表元素
void DprintLinkList(DuLinkList head) {DuLinkList p = head->next;while (p) {printf("%c", p->data);p = p->next;}printf("\n");
}

三、双链表的全部代码(C语言)

#include <stdio.h>#define OK 1
#define ERROR 0typedef char ElemType;
typedef int Status;typedef struct DuLNode {ElemType data;struct DuLNode *prior;struct DuLNode *next;
} DuLNode, *DuLinkList;//双链表初始化
Status DInitList(DuLinkList &head) {head = new DuLNode;head->prior = NULL;head->next = NULL;return OK;
}//功能菜单
int choice() {printf("==================================\n");printf("         双链表操作功能菜单        \n");printf("1、插入元素  2、查询表长  3、按位查找\n");printf("4、按值查找  5、删除元素  6、销毁链表\n");printf("7、清空链表  8、批量插入  9、链表元素\n");printf("==================================\n");return 0;
}//插入
Status DListInsert(DuLinkList &head, int i, ElemType e) {DuLinkList p = head;int j = 0;while (p && (j < i - 1)) {p = p->next;++j;}if (!p || j > i - 1) {return ERROR;}DuLNode *s = new DuLNode;s->data = e;s->next = p->next;if(p->next != NULL){p->next->prior = s;	}p->next = s;s->prior = p;return OK;
}//查找
int DLocateLinkListElem(DuLinkList head, ElemType e) {DuLinkList p = head->next;int j = 1;while (p && (p->data != e)) {p = p->next;j++;}if (p == NULL) { return 0;}return j;
}//取值
Status DGetLinkList(DuLinkList head, int i, ElemType &e) {DuLinkList p = head->next;int j = 1;while (p && j < i) {p = p->next;++j;}if (p == NULL) {return ERROR;}e = p->data;return OK;
}//求双链表长度
Status DGetLinkListLength(DuLinkList head) {DuLinkList p = head->next;int length = 0;while (p!=NULL) {            //单链表不为空表时length++;p = p->next;}return length;
}//删除
Status DListDelete(DuLinkList &head, int i, ElemType &e) {DuLinkList p = head;int j = 0;while (p && j < i - 1) {p = p->next;j++;}if (!p) {return ERROR;}DuLinkList q = p->next;e = q->data;p->next = q->next;if(q->next != NULL){q->next->prior=p;}delete q;return OK;
}//清空
Status DClearLinkList(DuLinkList &head) {DuLinkList p = head->next;DuLinkList q;while (p) {q = p;p = p->next;delete q;}head->next = NULL;return OK;
}//销毁
Status DestoryDLinkList(DuLinkList &head) {DuLinkList p;while (head) {p = head;head = head->next;delete p;}return OK;
}//输出链表元素
void DprintLinkList(DuLinkList head) {DuLinkList p = head->next;while (p) {printf("%c", p->data);p = p->next;}printf("\n");
}int main() {DuLinkList Dlist;printf("双链表正在初始化....\n");int InitStatus = DInitList(Dlist);if (InitStatus == OK) {printf("双链表初始化成功!\n");} else {printf("双链表初始化失败!\n");}choice();while (1) {int flag;printf("请输入所需的功能编号:\n");scanf("%d", &flag);switch (flag) {//通过开关进行功能选择case 1: {//插入元素//ListInsert_Dul(Dlist,1,'a');int insertIndex;ElemType inserElem;printf("请输入插入元素位置及插入元素(请在英文状态下输入例如:1,a): \n");scanf("%d,%c", &insertIndex, &inserElem);Status InsertS = DListInsert(Dlist, insertIndex, inserElem);if (InsertS == OK) {printf("向双链表%d个位置,插入元素为%c成功!\n\n", insertIndex, inserElem);} else {printf("向双链表插入元素失败!\n\n");}}break;case 2: {//求单链表的长度int length = DGetLinkListLength(Dlist);printf("循环双链表的长度为:%d。 \n\n", length);}break;case 3: {//取值Status GetIndex;printf("请输入需要查询的元素的位置:\n");scanf("%d", &GetIndex);ElemType GetElem;int GetStatus = DGetLinkList(Dlist, GetIndex, GetElem);if (GetStatus == OK) {printf("从单链表中获取第%d位置元素成功,所获取到的元素为:%c。\n\n", GetIndex, GetElem);} else {printf("从单链表中获取第%d位置元素失败!\n\n", GetIndex);}}break;case 4: {//查找ElemType LocateElem;printf("请输入想要查找元素:\n");getchar();    //用于接收回车scanf("%c", &LocateElem);Status LocateIndex = DLocateLinkListElem(Dlist, LocateElem);if (LocateIndex > 0) {printf("从双链表中查找元素%c成功,它在循环链表中的位置为第%d个!\n\n", LocateElem, LocateIndex);} else {printf("从双链表中查找元素%c失败!\n\n", LocateElem);}}break;case 5: {//删除//ListDelete_DuL(list,1);Status DeleteIndex;printf("请输入想要删除元素的位置:\n");scanf("%d", &DeleteIndex);ElemType DeleteElem;ElemType DeleteStatus = DListDelete(Dlist, DeleteIndex, DeleteElem);if (DeleteStatus == OK) {printf("删除双链表第%d个位置的元素成功,删除的元素为:%c。\n\n", DeleteIndex, DeleteElem);} else {printf("删除双链表第%d个位置的元素失败!\n\n", DeleteIndex);}}break;case 6: {//销毁Status DestoryStatus = DestoryDLinkList(Dlist);if (DestoryStatus == OK) {printf("双环链表销毁成功!\n\n");} else {printf("双链表销毁失败!\n\n");}}break;case 7: {//清空Status ClearStatus = DClearLinkList(Dlist);if (ClearStatus == OK) {printf("双链表清空成功!\n\n");} else {printf("双链表清空失败!\n\n");}}break;case 8: {//批量插入int on;printf("请输入想要插入的元素个数:\n");scanf("%d", &on);ElemType array[on];for (int i = 1; i <= on; i++) {getchar();printf("向双链表第%d个位置插入元素为:", (i));scanf("%c", &array[i]);}for (int i = 1; i <= on; i++) {Status InsertStatus = DListInsert(Dlist, i, array[i]);if (InsertStatus == OK) {printf("向双链表第%d个位置插入元素%c成功!\n", i, array[i]);} else {printf("向双链表第%d个位置插入元素%c失败!\n", i, array[i]);}}}break;case 9: {//输出链表元素DprintLinkList(Dlist);}break;default: {printf("输入错误,无此功能,请检查输入:\n\n");}}}return 1;}

四、运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【视频媒体】深入了解直播视频流

深入了解直播视频流&#x1f3a5; YouTube、TikTok live和Twitch上的直播视频是如何工作的&#xff1f; 直播视频流与常规流媒体不同&#xff0c;因为视频内容通过互联网近乎实时发送&#xff0c;通常只有几秒钟的延迟。 下图解释了实现这一目标背后所发生的事情。 步骤1&…

Numpy入门

Numpy入门 前言1. Numpy介绍2. Numpy中的array3. Numpy怎么对数组按照索引进行查询5. Numpy常用的random随机函数6. Numpy的数学统计函数7. Numpy计算数组中满足条件元素的个数8. Numpy怎样给数组增加一个维度&#xff08;转置&#xff09;9. Numpy非常重要的数据合并操作10. N…

[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

k8s图形化管理工具之rancher

前言 在前面的k8s基础学习中&#xff0c;我们学习了各种资源的搭配运用&#xff0c;以及命令行&#xff0c;声明式文件创建。这些都是为了k8s管理员体会k8s的框架&#xff0c;内容基础。在真正的生产环境中&#xff0c;大部分的公司还是会选用图形化管理工具来管理k8s集群&…

人工智能时代:让AIGC成为你的外部智慧源(文末送书)

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 什么是AIGC?二. AIGC如何运作&#xff1f;2.1 步骤一&#xff1a;收集数据2.…

爬虫是什么 怎么预防

爬虫是一种自动化程序&#xff0c;用于从网页或网站中提取数据。它们通过模拟人类用户的行为&#xff0c;发送HTTP请求并解析响应&#xff0c;以获取所需的信息。 爬虫可以用于各种合法用途&#xff0c;如搜索引擎索引、数据采集和监测等。然而&#xff0c;有些爬虫可能是恶意的…

【Fooocus 深度学习】SDXL,AIGC生图,源码解读

文章目录 使用通配符增加prompt多样性Fooocus的风格实现 使用通配符增加prompt多样性 prompt和negative_prompt都可以通过apply_wildcards函数来实现通配符替换&#xff0c;apply_wildcards会从txt中随机找一个出来。 promptsunshine, river, trees, __artist__ task_prompt …

固态硬盘优化设置

目录 前言&#xff1a; 关闭Windows Search 禁用系统保护&#xff08;不建议&#xff09; 不建议禁用系统保护原因 关闭碎片整理 提升固态硬盘速度 开启TRIM 合理使用固态硬盘的容量 正确关机 关闭开机自启 前言&#xff1a; 电脑配备固态硬盘就能一劳永逸吗&#…

docker 安装python3.8环境镜像并导入局域网

一、安装docker yum -y install docker docker version #显示 Docker 版本信息 可以看到已经下载下来了 拉取镜像python3镜像 二、安装docker 中python3环境 运行本地镜像&#xff0c;并进入镜像环境 docker run -itd python-38 /bin/bash docker run -itd pyth…

Qt-QFileDialog保存文件及获取带扩展名的文件名

正确用法 QFileDialog dialog(this, "Save File", QDir::currentPath(), "Text Files (.txt)"); dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setDefaultSuffix("txt"); // << if (!dialog.exec())return; QString fileName …

uniapp 用css animation做的鲤鱼跃龙门小游戏

第一次做这种小游戏&#xff0c;刚开始任务下来我心里是没底的&#xff0c;因为我就一个‘拍黄片’的&#xff0c;我那会玩前端的动画啊&#xff0c;后面尝试写了半天&#xff0c;当即我就给我领导说&#xff0c;你把我工资加上去&#xff0c;我一个星期给你做出来&#xff0c;…

【嵌入式学习】网络通信基础-项目篇:简单UDP聊天室

源码已在GitHub开源&#xff1a;0clock/LearnEmbed-projects/chat 实现的功能 客户端功能&#xff1a; 上线发送登录的用户名[yes] 发送消息和接收消息[yes] quit退出 服务器端功能&#xff1a; 统计用户上线信息&#xff0c;放入链表中[yes] 接收用户信息并给其他用户发送消…

Scapy编程指南(基础概念)

Scapy编程指南&#xff08;基础概念&#xff09; Scapy是什么 Scapy是Python中一个非常强大的库&#xff0c;它专门用于处理、发送和捕获网络协议中的数据包&#xff0c;它允许开发人员通过Python代码构建、解析和发送自定义网络协议的数据包。Scapy提供了一种直观、灵活的方…

k8s---包管理器helm

内容预知 目录 内容预知 helm相关知识 Helm的简介与了解 helm的三个重要概念 helm的安装和使用 将软件包拖入master01上 使用 helm 安装 Chart 对chart的基本使用 查看chart信息 安装chart 对chart的基本管理 helm自定义模板 在镜像仓库中拉取chart&#xff0c;查…

【操作系统】实验七 显示进程列表

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

深度学习记录--Momentum gradient descent

Momentum gradient descent 正常的梯度下降无法使用更大的学习率&#xff0c;因为学习率过大可能导致偏离函数范围&#xff0c;这种上下波动导致学习率无法得到提高&#xff0c;速度因此减慢(下图蓝色曲线) 为了减小波动&#xff0c;同时加快速率&#xff0c;可以使用momentum…

数据结构(数组)

一.数组的概念 1. 数组定义 数组(Array)是一种线性结构。它用一组连续的内存空间&#xff0c;来存储一组具有相同数据类型的数据。 2. 数组的特点 ①用来存储一组类型相同的数据。 ②在内存中&#xff0c;分配连续的空间&#xff0c;数组创建时需要指定容量。因为数组为了保持内…

ZK高可用架构涉及常用功能整理

ZK高可用架构涉及常用功能整理 1. zk的高可用系统架构和相关组件1.1 Quorum机制1.2 ZAB协议 2. zk的核心参数2.1 常规配置2.2 特殊优化配置 3. zk常用命令3.1 常用基础命令3.2 常用运维命令 4. 事务性4.1 数据写流程4.2 数据读流程 5. 疑问和思考5.1 zk不擅长处理哪些场景&…

书生·浦语大模型实战营-学习笔记6

目录 OpenCompass大模型测评1. 关于评测1.1 为什么要评测&#xff1f;1.2 需要评测什么&#xff1f;1.3 如何评测&#xff1f;1.3.1 客观评测1.3.2 主观评测1.3.3 提示词工程评测 2. 介绍OpenCompass工具3. 实战演示 OpenCompass大模型测评 1. 关于评测 1.1 为什么要评测&#…

仿真机器人-深度学习CV和激光雷达感知(项目2)day5【作业1与答案1】

文章目录 前言作业1答案1 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本文内容是我为复试准备的第二个项目 &#x1f4ab;欢迎大家的关注&#xff0c;我的博客主要关注于考研408以及AIoT的内容 &#x1f31f; 预置知识…