双向链表、单双向链表比较、双向链表的基本操作

我要成为嵌入式高手之3月20日数据结构第三天!!
————————————————————————————

双向链表

        双向链表与单向链表的区别:双向链表中的结点的指针域包含前驱结点的地址,而单向链表的结点中指针域只有后驱结点的地址。

        双向链表操作前驱结点比单向链表方便:单向链表若是要操作前驱结点就始终要用一个指针指向前驱结点,否则很容易丢失前驱结点地址,就要重新进行遍历。

1、创建链表

TWO_LIST *CreateLink()
{TWO_LIST *plist = malloc(sizeof(TWO_LIST));if (NULL == plist){perror("fail to malloc list");return NULL;}plist->phead = NULL;plist->clen = 0;return plist;
}

2、创建结点

TWO_NODE *CreateNode(DATA_STU data)
{TWO_NODE *pnode = malloc(sizeof(TWO_NODE));if (NULL == pnode){perror("fail to malloc node");return NULL;}pnode->data = data;pnode->ppre = NULL;pnode->pnext = NULL;return pnode;
}

3、头插

int PushHeadNode(TWO_LIST *plist, TWO_NODE *pnode)
{if (pnode == NULL || plist == NULL){return -1;}if (plist->phead == NULL){plist->phead = pnode;}else{pnode->pnext = plist->phead;plist->phead->ppre = pnode;plist->phead = pnode;}plist->clen++;return 0;
}

4、尾插

int PushTailNode(TWO_LIST *plist, TWO_NODE *pnode)
{TWO_NODE *ptmp = NULL;if (pnode == NULL || plist == NULL){return -1;}if (plist->phead == NULL){plist->phead = pnode;}else{ptmp = plist->phead;while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = pnode;pnode->ppre = ptmp;}plist->clen++;return 0;
}

5、从头遍历

int SearchHeadAll(TWO_LIST *plist)
{TWO_NODE *ptmp = plist->phead;if (plist->phead == NULL){printf("NO NODE!\n");return -1;}else{while (ptmp != NULL){printf("StuInfo:\nid = %d; name = %s; score = %d.\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->pnext;}}printf("len = %d\n", plist->clen);return 0;
}

6、从尾遍历

int SearchTailAll(TWO_LIST *plist)
{TWO_NODE *ptmp = plist->phead;if (plist->phead == NULL){printf("NO NODE!\n");return -1;}else{while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}while (ptmp != NULL){printf("StuInfo:\nid = %d; name = %s; score = %d.\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->ppre;}}printf("len = %d\n", plist->clen);return 0;
}

7、查找

TWO_NODE *SearchInLink(TWO_LIST *plist, int id)
{TWO_NODE *dest = plist->phead;while (dest != NULL){if (dest->data.id != id){dest = dest->pnext;}else{return dest;}}return NULL;
}

8、修改

int ChangeInLink(TWO_LIST *plist, int uid, DATA_STU sdata)
{TWO_NODE *ptmp = plist->phead;while (ptmp != NULL){if (ptmp->data.id != uid){ptmp = ptmp->pnext;}else{ptmp->data = sdata;return 1;}}return -1;
}

9、头删

int PopHeadLink(TWO_LIST *plist)
{TWO_NODE *pfree = plist->phead;if (NULL == plist->phead){return -1;}else{pfree->pnext->ppre = NULL;plist->phead = pfree->pnext;free(pfree);plist->clen--;}return 0;
}

10、尾删

int PopTailLink(TWO_LIST *plist)
{TWO_NODE *pfree = plist->phead;if (NULL == plist->phead){return -1;}else if (NULL == plist->phead->pnext){free(pfree);}else{while (pfree->pnext != NULL){pfree = pfree->pnext;}pfree->ppre->pnext = NULL;free(pfree);}plist->clen--;return 0;
}

11、销毁

int DestroyLink(TWO_LIST *plist)
{TWO_NODE *pfree = NULL;TWO_NODE *ptmp = plist->phead;if (NULL == plist->phead){free(plist);}else{while (NULL != ptmp){pfree = ptmp;ptmp = ptmp->pnext;plist->phead = ptmp;free(pfree);}free(plist);}return 0;
}

 完整代码:

头文件:

#ifndef _LINK_H_
#define _LINK_H_#include <stdio.h>
#include <stdlib.h>/* 存储的数据类型 */
typedef struct stu
{int id;char name[32];int score;
}DATA_STU;/* 链表的结点类型 */
typedef struct node
{DATA_STU data;        //数据域struct node *pnext;    //后驱结点struct node *ppre;     //前驱结点
}TWO_NODE;/* 描述链表属性的标签类型 */
typedef struct list
{TWO_NODE *phead;      //存储头结点地址的指针int clen;              //链表中当前结点个数
}TWO_LIST;extern TWO_LIST *CreateLink();
extern TWO_NODE *CreateNode(DATA_STU data);
extern int PushHeadNode(TWO_LIST *plist, TWO_NODE *pnode);
extern int SearchHeadAll(TWO_LIST *plist);
extern int SearchTailAll(TWO_LIST *plist);
extern int PushTailNode(TWO_LIST *plist, TWO_NODE *pnode);
extern TWO_NODE *SearchInLink(TWO_LIST *plist, int id);
extern int ChangeInLink(TWO_LIST *plist, int uid, DATA_STU sdata);
extern int PopHeadLink(TWO_LIST *plist);
extern int PopTailLink(TWO_LIST *plist);
extern int DestroyLink(TWO_LIST *plist);#endif

功能函数文件:

#include "head.h"TWO_LIST *CreateLink()
{TWO_LIST *plist = malloc(sizeof(TWO_LIST));if (NULL == plist){perror("fail to malloc list");return NULL;}plist->phead = NULL;plist->clen = 0;return plist;
}TWO_NODE *CreateNode(DATA_STU data)
{TWO_NODE *pnode = malloc(sizeof(TWO_NODE));if (NULL == pnode){perror("fail to malloc node");return NULL;}pnode->data = data;pnode->ppre = NULL;pnode->pnext = NULL;return pnode;
}int PushHeadNode(TWO_LIST *plist, TWO_NODE *pnode)
{if (pnode == NULL || plist == NULL){return -1;}if (plist->phead == NULL){plist->phead = pnode;}else{pnode->pnext = plist->phead;plist->phead->ppre = pnode;plist->phead = pnode;}plist->clen++;return 0;
}int SearchHeadAll(TWO_LIST *plist)
{TWO_NODE *ptmp = plist->phead;if (plist->phead == NULL){printf("NO NODE!\n");return -1;}else{while (ptmp != NULL){printf("StuInfo:\nid = %d; name = %s; score = %d.\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->pnext;}}printf("len = %d\n", plist->clen);return 0;
}int SearchTailAll(TWO_LIST *plist)
{TWO_NODE *ptmp = plist->phead;if (plist->phead == NULL){printf("NO NODE!\n");return -1;}else{while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}while (ptmp != NULL){printf("StuInfo:\nid = %d; name = %s; score = %d.\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->ppre;}}printf("len = %d\n", plist->clen);return 0;
}int PushTailNode(TWO_LIST *plist, TWO_NODE *pnode)
{TWO_NODE *ptmp = NULL;if (pnode == NULL || plist == NULL){return -1;}if (plist->phead == NULL){plist->phead = pnode;}else{ptmp = plist->phead;while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = pnode;pnode->ppre = ptmp;}plist->clen++;return 0;
}TWO_NODE *SearchInLink(TWO_LIST *plist, int id)
{TWO_NODE *dest = plist->phead;while (dest != NULL){if (dest->data.id != id){dest = dest->pnext;}else{return dest;}}return NULL;
}int ChangeInLink(TWO_LIST *plist, int uid, DATA_STU sdata)
{TWO_NODE *ptmp = plist->phead;while (ptmp != NULL){if (ptmp->data.id != uid){ptmp = ptmp->pnext;}else{ptmp->data = sdata;return 1;}}return -1;
}int PopHeadLink(TWO_LIST *plist)
{TWO_NODE *pfree = plist->phead;if (NULL == plist->phead){return -1;}else{pfree->pnext->ppre = NULL;plist->phead = pfree->pnext;free(pfree);plist->clen--;}return 0;
}int PopTailLink(TWO_LIST *plist)
{TWO_NODE *pfree = plist->phead;if (NULL == plist->phead){return -1;}else if (NULL == plist->phead->pnext){free(pfree);}else{while (pfree->pnext != NULL){pfree = pfree->pnext;}pfree->ppre->pnext = NULL;free(pfree);}plist->clen--;return 0;
}int DestroyLink(TWO_LIST *plist)
{TWO_NODE *pfree = NULL;TWO_NODE *ptmp = plist->phead;if (NULL == plist->phead){free(plist);}else{while (NULL != ptmp){pfree = ptmp;ptmp = ptmp->pnext;plist->phead = ptmp;free(pfree);}free(plist);}return 0;
}

主函数文件

#include "head.h"int main(void)
{TWO_LIST *plist = NULL;TWO_NODE *pnode = NULL;int i = 0;int uid = 0;/* 创建双向链表 */plist = CreateLink();if (NULL == plist){perror("fail to CreateLink");return -1;}/* 初始化要插入结点的数据 */DATA_STU data[5] = {{1, "zhangsan", 99},{2, "lisi", 98},{3, "wangwu", 97},{4, "aaaaa", 96},{5, "bbbbb", 95},};DATA_STU data1[5] = {{6, "zhangsan", 99},{7, "lisi", 98},{8, "wangwu", 97},{9, "aaaaa", 96},{10, "bbbbb", 95},};/* 创建头插结点并头插 */for (i = 0; i < 5; ++i){pnode = CreateNode(data[i]);if (NULL == pnode){perror("fail to CreateNode");return -1;}PushHeadNode(plist, pnode);}
#if 0/* 从头遍历、从尾遍历*/SearchHeadAll(plist);printf("==============================\n");SearchTailAll(plist);printf("TAIL==========================\n");
#endif/* 创建尾插结点并尾插 */for (i = 0; i < 5; ++i){pnode = CreateNode(data1[i]);if (NULL == pnode){perror("fail to CreateNode");return -1;}PushTailNode(plist, pnode);}
#if 0/* 双向遍历 */SearchHeadAll(plist);printf("==========================\n");SearchTailAll(plist);
#endif
#if 0/* 查找对应id号的学生信息 */printf("==========================\n");printf("Input stu id to search:\n");scanf("%d", &uid);TWO_NODE *dest = SearchInLink(plist, uid);if (NULL == dest){printf("NO STUDENT!\n");}else{printf("The Dest StuInfo:\nid = %d; name = %s; score = %d.\n", dest->data.id, dest->data.name, dest->data.score);}#endif#if 0/* 修改对应id号的学生信息 */DATA_STU sdata = {0};printf("==========================\n");printf("Input stu id to change:\n");scanf("%d", &sdata.id);printf("Input stu info to change:\nname:");scanf("%s", sdata.name);printf("score:");scanf("%d", &sdata.score);putchar('\n');ChangeInLink(plist, sdata.id, sdata);SearchHeadAll(plist);
#endif
#if 0/* 头删 */SearchHeadAll(plist);printf("==================================\n");PopHeadLink(plist);SearchHeadAll(plist);
#endif
#if 0/* 尾删 */SearchHeadAll(plist);printf("==================================\n");PopTailLink(plist);PopTailLink(plist);PopTailLink(plist);PopTailLink(plist);SearchHeadAll(plist);
#endif
#if 1/* 销毁 */SearchHeadAll(plist);printf("==================================\n");SearchTailAll(plist);DestroyLink(plist);#endifreturn 0;
}

Makefile文件

all:doulinkdoulink:main.c twolink.cgcc $^ -o $@.PHONY:
clean:rm doulink;

作业:

12、删除双向链表指定结点

int DeleteIdNode(TWO_LIST *plist, int uid)
{TWO_NODE *dest = plist->phead;while (dest != NULL){if (dest->data.id != uid){dest = dest->pnext;}else{dest->ppre->pnext = dest->pnext;dest->pnext->ppre = dest->ppre;free(dest);plist->clen--;}}return 0;
}

 

13、双向链表倒置

int ReverseTwoLink(TWO_LIST *plist)
{TWO_NODE *ptmp = plist->phead;TWO_NODE *pver = NULL;struct node *p = NULL;if (plist->phead == NULL || plist->phead->pnext == NULL){return -1;}while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}plist->phead = ptmp;while (ptmp != NULL){pver = ptmp;ptmp = ptmp->ppre;p = pver->pnext;pver->pnext = pver->ppre;pver->ppre = p;}return 0;
}

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

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

相关文章

Q-Tester:适用于开发、生产和售后的诊断测试软件

Q-Tester.Expert是一款基于ODX&#xff08;ASAM MCD-2D / ISO 22901-1&#xff09;国际标准的工程诊断仪。通过此诊断仪可实现与ECU控制器之间的数据交互。这一基于ODX国际标准的解决方案&#xff0c;其优势在于&#xff1a;ODX数据库不仅可在开发部门交互&#xff0c;而且可在…

DML - 增删改(insert into,delete,update)

引言&#xff1a;对比DB / 表结构 : create , drop , alter 本次记录 数据操作 语言&#xff1a; 1.进入 hive 数据库&#xff0c;再打开 ryx1 表 2. insert select 3. update select 4. delete select

python---练习2

1、打印图案 &#xff08;1&#xff09;直角三角形 #多层循环layer int(input("请输入您要打印的层数&#xff1a; "))index 1 while index < layer : #外层循环控制层数j 1while j < index : #内层循环控制每层个数print (&qu…

C++进阶:二叉搜索树介绍、模拟实现(递归迭代两版本)及其应用

上次介绍完多态后&#xff1a;C进阶&#xff1a;详解多态&#xff08;多态、虚函数、抽象类以及虚函数原理详解&#xff09; 也是要开始继续学习了 文章目录 1.二叉搜索树1.1概念1.2二叉搜索树特性1.3 二叉搜索树的操作 2.模拟实现2.1项目文件规划2.2基本结构2.3各种接口、功能…

kafka集群介绍及搭建

介绍 kafka是一个高性能、低延迟、分布式的消息传递系统&#xff0c;特点在于实时处理数据。集群由多个成员节点broker组成&#xff0c;每个节点都可以独立处理消息传递和存储任务。 路由策略 发布消息由key、value组成&#xff0c;真正的消息是value&#xff0c;key是标识路…

【prometheus-operator】k8s监控集群外redis

1、部署exporter GitHub - oliver006/redis_exporter: Prometheus Exporter for Redis Metrics. Supports Redis 2.x, 3.x, 4.x, 5.x, 6.x, and 7.x redis_exporter-v1.57.0.linux-386.tar.gz # 解压 tar -zxvf redis_exporter-v1.57.0.linux-386.tar.gz # 启动 nohup ./redi…

Java基础 学习笔记九

for循环 for循环语句的语法结构 for(初始化表达式;条件表达式;更新表达式){循环体;}初始化表达式最先被执行&#xff0c;而且只执行一次条件表达式的执行结果必须是一个布尔类型的值更新表达式一般是负责更新某个变量值的&#xff08;只有更新了某个变量值&#xff0c;条件表达…

Visual Studio 2013 - 重置窗口布局

Visual Studio 2013 - 重置窗口布局 1. Microsoft Visual Studio 2013 - 重置窗口布局References 1. Microsoft Visual Studio 2013 - 重置窗口布局 窗口 -> 重置窗口布局 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

API接口采集淘宝商品详情数据获取属性价格详情图等

什么是电商APIAPI全称应用程序编程接口&#xff08;Application Programming Interface&#xff09;&#xff0c;是一组用于访问某个软件或硬件的协议、规则和工具集合。电商API就是各大电商平台提供给开发者访问平台数据的接口。目前&#xff0c;主流电商平台如淘宝、天猫、京…

软件工程导论画图题汇总:期末+复试

文章目录 一、数据模型&#xff1a;实体联系图&#xff08;E-R图&#xff09;二、行为模型&#xff1a;状态转换图三、功能模型&#xff1a;数据流图四、数据字典五、系统流程图六、层次图七、HIPO图八、结构图九、程序流程图十、盒图十一、PAD图十二、判定表、判定树 一、数据…

EF数据持久化(三层架构,客户增删)

效果图 点击新增按钮 点击添加 添加成功展示新增数据 点击删除&#xff0c;出现删除选项&#xff0c;点击确定根据id删除成功 成功删除 实现过程 Model设置具体流程在下面链接中 https://blog.csdn.net/Mr_wangzu/article/details/136805824?spm1001.2014.3001.5501 DAL …

函数栈帧的创建和销毁 - 局部变量|函数传参|函数调用|函数返回|图文详解

目录 1.寄存器EBP和ESP 2.函数栈帧的创建 3.函数的调用 4. 函数栈帧的销毁 函数栈帧&#xff08;function stack frame&#xff09;是在函数调用期间在栈上分配的内存区域&#xff0c;用于存储函数的局部变量、参数、以及用于函数调用和返回的相关信息。每当函数被调用时&a…

ros小问题之差速轮式机器人轮子不显示(rviz gazebo)

在rviz及gazebo练习差速轮式机器人时&#xff0c;很奇怪&#xff0c;只有个机器人的底板及底部的两个万向轮&#xff0c;如下图&#xff0c; 后来查看相关.xacro文件&#xff0c;里面是引用包含了轮子的xacro文件&#xff0c;只需传入不同的参数即可调用生成不同位置的轮子&…

1058:求一元二次方程

【题目描述】 利用公式 求一元二次方程axbxc0的根&#xff0c;其中a不等于0。结果要求精确到小数点后5位。 【输入】 输入一行&#xff0c;包含三个浮点数a,b,c&#xff08;它们之间以一个空格分开&#xff09;&#xff0c;分别表示方程axbxc0的系数。 【输出】 输出一行&…

航顺车规级SoC全新亮相,助推汽车智能化发展

受益于汽车电动化、智能化和网联化的推进&#xff0c;汽车车身域和座舱域MCU市场规模持续扩大。据统计&#xff0c;2021年中国车载芯片MCU市场规模达30.01亿美元&#xff0c;同比增长13.59%&#xff0c;预计2025年市场规模将达42.74亿美元。 在技术要求方面&#xff0c;对…

MyBatisPlus 之四:MP 的乐观锁和逻辑删除、分组、排序、链式的实现步骤

乐观锁 乐观锁是相对悲观锁而言的&#xff0c;乐观锁假设数据一般情况不会造成冲突&#xff0c;所以在数据进行提交更新的时候&#xff0c;才会正式对数据的冲突与否进行检测&#xff0c;如果冲突&#xff0c;则返回给用户异常信息&#xff0c;让用户决定如何去做。 乐观锁适用…

[Qt学习笔记]QT下获取Halcon图形窗口鼠标事件并执行相应操作

目录 1、背景2、参考信息3、目标4、步骤4.1 Halcon库的配置4.2 读取图像&#xff0c;并实现图像自适应窗体控件大小4.3 主要的图形绘制和贴图操作见如下代码&#xff0c;其中重点为全局函数的创建来实现选择Select、拖拽Drag和尺寸Resize事件响应。 5、总结 1、背景 在视觉项目…

3.19作业

1、思维导图 2、模拟面试题 1&#xff09;TCP通信中的三次握手和四次挥手 答&#xff1a;三次握手 客户端向服务器发送连接请求 服务器向客户端回复应答并向客户端发送连接请求 客户端回复服务端&#xff0c;并建立联系 四次挥手 进程a向进程b发送断开连接请求…

3.20作业

1、思维导图 2、 1> 创建一个工人信息库&#xff0c;包含工号&#xff08;主键&#xff09;、姓名、年龄、薪资。 2> 添加三条工人信息&#xff08;可以完整信息&#xff0c;也可以非完整信息&#xff09; 3> 修改某一个工人的薪资&#xff08;确定的一个&am…

踏“时间”与“空间”前来探寻复杂度的奥妙(Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…