当前位置: 首页 > news >正文

数据结构——双向链表

双向链表的结构:

在这里插入图片描述

双向链表由链表对象,头结点,中间结点以及尾结点组成每一部分结点结构或是指针内容存在差异,需要牢记双向链表的结构,双向链表的结构使我们能够通过一个中间节点找到它前后的结点,这是与单向链表的最大区别。

需要熟练掌握的基本操作:

在这里插入图片描述

让我们在记牢理解双向链表的结构以后直接上代码练习

封装双向链表:1:头文件定义双向链表的结构

#ifndef __DOULINK_H__
#define __DOULINK_H__
//双向链表存储的数据类型
typedef struct stu
{int id;char name[32];int score;
}Data_type_t;/*双向链表的结点类型*/
typedef struct dounode
{Data_type_t data;struct dounode *ppre;  //指向前驱结点的指针struct dounode *pnext; //指向后继结点的指针
}DNode_t;/*双向链表对象类型*/
typedef struct doulink
{DNode_t *phead;   //双向链表头结点地址int clen;         //双向链表结点个数
}DLink_t;
extern DLink_t *create_doulink();
extern int insert_doulink_head(DLink_t *pdlink, Data_type_t data);
extern int is_empty_doulink(DLink_t *pdlink);
extern void doulink_for_each(DLink_t *pdlink, int dir);
extern int insert_doulink_tail(DLink_t *pdlink, Data_type_t data);
extern int delete_doulink_head(DLink_t *pdlink);
extern int delete_doulink_tail(DLink_t *pdlink);

使用头插法构建双向链表:头插法是重点

#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>DLink_t *create_doulink()
{DLink_t *pdlink= malloc(sizeof(DLink_t));if (NULL == pdlink){printf("malloc error");return NULL;}pdlink->phead = NULL;pdlink->clen = 0;return pdlink;
}int is_empty_doulink(DLink_t *pdlink)
{return NULL == pdlink->phead;}int insert_doulink_head(DLink_t *pdlink, Data_type_t data)
{DNode_t *pnode = malloc(sizeof(DNode_t));if (NULL == pnode){printf("malloc error");return -1;}pnode->data = data;pnode->ppre = NULL;pnode->pnext = NULL;if (is_empty_doulink(pdlink)){pdlink->phead = pnode;}else{pnode->pnext = pdlink->phead;pdlink->phead->ppre = pnode;pdlink->phead = pnode;}pdlink->clen++;return 0;
}

主函数部分:

#include <stdio.h>
#include "doulink.h"int main(void)
{Data_type_t stus[5] = {{1, "zhangsan", 99},{2, "lisi", 100}, {3, "wangwu", 90}, {4, "maliu", 56}, {5, "tianqi", 66}};DLink_t *pdlink = create_doulink();if (NULL == pdlink){return -1;}insert_doulink_head(pdlink, stus[0]);insert_doulink_head(pdlink, stus[1]);insert_doulink_head(pdlink, stus[2]);insert_doulink_tail(pdlink, stus[3]);insert_doulink_tail(pdlink, stus[4]);

构建好双向链表后,对于双向链表的各种基本操作:

遍历打印:dir1顺序打印,direlse逆序打印

void doulink_for_each(DLink_t *pdlink, int dir)
{if (is_empty_doulink(pdlink)){return ;}DNode_t *ptmp = pdlink->phead;if (dir){while (ptmp != NULL){printf("%d %s %d\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->pnext;}}else{while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}while (ptmp != NULL){printf("%d %s %d\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->ppre;}}printf("\n");
}

尾插法

int insert_doulink_tail(DLink_t *pdlink, Data_type_t data)
{DNode_t *pnode = malloc(sizeof(DNode_t));if (NULL == pnode){printf("malloc error\n");return -1;}pnode->data = data;pnode->ppre = NULL;pnode->pnext = NULL;if (is_empty_doulink(pdlink)) //空链表情况{pdlink->phead = pnode;}else //非空链表情况{DNode_t *ptmp = pdlink->phead;while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = pnode;pnode->ppre = ptmp;}pdlink->clen++;return 0;
}

删除头结点:

int delete_doulink_head(DLink_t *pdlink)
{if (is_empty_doulink(pdlink)){return -1;}DNode_t *pdel = pdlink->phead;pdlink->phead = pdel->pnext;if (pdlink->phead != NULL){pdlink->phead->ppre = NULL;}free(pdel);pdlink->clen--;return 0;
}

删除尾结点:

int delete_doulink_tail(DLink_t *pdlink)
{if (is_empty_doulink(pdlink)){return -1;}DNode_t *ptmp = pdlink->phead;if (1 == pdlink->clen){free(ptmp);pdlink->phead = NULL;}else{while (ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->ppre->pnext = NULL;free(ptmp);}pdlink->clen--;return 0;
}

销毁链表

int destory_dblink(dbLINK_T *plink)
{if(is_empty_doubleLink(plink)){printf("空结点");return -1;}dbNODE_T *p=plink->phead;while(p!=NULL){p=p->pnext;head_node_delet(plink);}free(plink);return 0;}

== 这个销毁方法无法销毁主函数里面创造的plink==,,这时我们使用二级指针销毁主函数以及封装函数里的双向链表

在这里插入图片描述

查找结点并返回其地址

dbNODE_T *findnode(dbLINK_T *plink,char name[20])
{if(is_empty_doubleLink(plink)){printf("空链表,无结点可查");return NULL;}dbNODE_T *p=plink->phead;while (p!=NULL){if(strcmp(p->data.name,name)==0){return p;}p=p->pnext;}printf("查找不到该学生");    return NULL;
}

根据名字修改学生分数

int findnodeAndChangeScore(dbLINK_T *plink,char name[20],int newscore)
{if(is_empty_doubleLink(plink)){printf("空链表,无结点可查");return -1;}dbNODE_T *p=plink->phead;while (p!=NULL){if(strcmp(p->data.name,name)==0){p->data.score=newscore;return 0;}p=p->pnext;}printf("查找不到该学生");    return -1;
}

查找结点并删除该结点:

int findnodeAndDELETnode(dbLINK_T *plink, char name[20])
{if(is_empty_doubleLink(plink)){printf("空链表,无结点可查\n");return -1;}dbNODE_T *p = plink->phead;// 遍历整个链表查找节点while (p != NULL){if(strcmp(p->data.name, name) == 0){// 情况1:删除头节点if(p->ppre == NULL){head_node_delet(plink);}// 情况2:删除尾节点else if(p->pnext == NULL){p->ppre->pnext = NULL;free(p);plink->clen--;}// 情况3:删除中间节点else{p->ppre->pnext = p->pnext;p->pnext->ppre = p->ppre;free(p);plink->clen--;}printf("找到并删除该学生节点\n");return 0;}p = p->pnext;}// 遍历完未找到节点printf("无法找到该同学,无法删除结点\n");return -1;
}

主函数

#include<stdio.h>
#include"doublelink.h"
int main(void)
{STUDENT_T stus[5]={{1,"zhangsan",99},{2,"lisi",100},{3,"wangwu",90},{4,"maliu",56},{5,"tianqi",66}};dbLINK_T *plink=creatlink(plink);if(plink==NULL){printf("mallol error");return -1;}creat_db_NODE(plink,stus[0]);creat_db_NODE(plink,stus[1]);creat_db_NODE(plink,stus[2]);creat_db_NODE(plink,stus[3]);creat_db_NODE(plink,stus[4]);/*  insert_dblink_tail(plink,stus[4]);leach_dblink(plink,1);head_node_delet(plink);deletLink_fromTheLastNODE(plink);*/leach_dblink(plink,1);/*  dbNODE_T *ret=findnode(plink,"wangwu");if(ret==NULL){return -1;}printf("学生名:%p\n",ret);*//*  findnodeAndChangeScore(plink,"lisi",50);leach_dblink(plink,1);*/findnodeAndDELETnode(plink,"wangwu");leach_dblink(plink,1);destory_dblink(plink);//  leach_dblink(plink,0);return 0;
}
http://www.dtcms.com/a/316925.html

相关文章:

  • 【学习嵌入式day-17-数据结构-单向链表/双向链表】
  • C语言:预处理、 库文件、 文件IO
  • Python深度学习:从入门到进阶
  • GPT-1、GPT-2、GPT-3 的区别和联系
  • C语言基础_IDE、进制转换、基本数据类型、输入输出函数、运算符
  • 一文搞定JavaServerPages基础,从0开始写一个登录与人数统计页面
  • 模拟面试总结
  • JSP相关Bug解决
  • Vue.js 教程
  • 市场与销售协同:CRM如何打破部门数据孤岛?
  • 思途Mybatis学习 0805
  • 一个小巧神奇的 USB数据线检测仪
  • LabVIEW 2025 安装攻略(附图文教程)适用于测试与自动控制领域
  • 亚马逊广告进阶指南:大词 VS 长尾词
  • 数据结构2.(双向链表,循环链表及内核链表)
  • 怎么在公司存活下去
  • SAP FI模块凭证增强逻辑的策略
  • 飞算 JavaAI:开启 Java 开发智能自动化新时代
  • open3d python 鞋底点云点胶路径识别
  • windows 系统装机入职版
  • Java 模版进阶
  • C#案例实战
  • 18day-人工智能-机器学习-分类算法-朴素贝叶斯分类
  • 8.5学习总结
  • Linux下部署Minecraft服务器
  • sqli-labs靶场less36-less40
  • 计算机二级java选择题真题【内附解析】
  • 页表实现机制,分页的缺点,三层页表的原理,页表的意义
  • 微软Dragon Ambient eXperience (DAX) 深度解析
  • mq_open系统调用及示例