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

[数据结构]#3 循环链表/双向链表

循环链表
简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或头结点,链表就成了一个环,头尾相连,就成了循环链表——circultlar linker list。

注意非空表,和空表。多数会加入头结点。
原来结束的条件是:
p->next != NULL ——> p-next != Head 

我们再结合单向链表的结构,则可得到更加实用的双向链表——double link list。

其基本框架的搭建:

#include "DouLink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//创建双向链表
DouLinkList *CreateDouLinkList()
{DouLinkList *dl = malloc(sizeof(DouLinkList));if (NULL == dl){fprintf(stderr, "CreateDouLinkList malloc\n");return NULL;}dl->head = NULL;dl->clen = 0;return dl;
}//检查是否为空
int IsEmpytDouLinkList(DouLinkList *dl)
{return 0 == dl->clen;
}//打印
int ShowDouLinkList(DouLinkList *dl, SHOW_DIR dir)
{int size = GetSizeDouLinkList(dl);DouLinkNode *tmp = dl->head;if (DIR_FORWARD == dir){for (int i = 0; i < size; i++){printf("name:%s sex:%c age:%d score:%d\n", tmp->data.name, tmp->data.sex,tmp->data.age, tmp->data.score);tmp = tmp->next;}}else{while (tmp->next){tmp = tmp->next;}for (int i = 0; i < size; i++){printf("name:%s sex:%c age:%d score:%d\n", tmp->data.name, tmp->data.sex,tmp->data.age, tmp->data.score);tmp = tmp->prev;}}
}//有效元素个数
int GetSizeDouLinkList(DouLinkList *dl)
{return dl->clen;
}//释放内存
int DestroyDouLinkList(DouLinkList *dl)
{DouLinkNode *tmp = dl->head;int size = GetSizeDouLinkList(dl);for (int i = 0; i < size; i++){tmp = dl->head;dl->head = dl->head->next;free(tmp);}free(dl);return 0;
}

然后是双向链表的操作(增、删、改、查):

//头插
int InsertHeadDouLinkList(DouLinkList *dl, DATATYPE *data)
{DouLinkNode *newnode = malloc(sizeof(DouLinkNode));if (NULL == newnode){fprintf(stderr, "InsertHeadDouLinkList malloc\n");return 1;}memcpy(&newnode->data, data, sizeof(DATATYPE));newnode->next = NULL;newnode->prev = NULL;if (IsEmpytDouLinkList(dl)){dl->head = newnode;}else{newnode->next = dl->head;dl->head->prev = newnode;dl->head = newnode;}dl->clen++;return 0;
}//尾插
int InsertTailDouLinkList(DouLinkList *dl, DATATYPE *data)
{if (IsEmpytDouLinkList(dl)){return InsertHeadDouLinkList(dl, data);}DouLinkNode *newnode = malloc(sizeof(DouLinkNode));if (NULL == newnode){fprintf(stderr, "InsertTailDouLinkList malloc\n");return 1;}memcpy(&newnode->data, data, sizeof(DATATYPE));newnode->next = NULL;newnode->prev = NULL;DouLinkNode *tmp = dl->head;while (tmp->next){tmp = tmp->next;}// init_nodenewnode->prev = tmp;tmp->next = newnode;dl->clen++;return 0;
}//按位置插入
int InsertPosDouLinkList(DouLinkList *dl, DATATYPE *data, int pos)
{int size = GetSizeDouLinkList(dl);if (pos < 0 || pos > size){return 1;}if (0 == pos)  // head{return InsertHeadDouLinkList(dl, data);}else if (pos == size)  // tail{return InsertTailDouLinkList(dl, data);}else  // mid{DouLinkNode *tmp = dl->head;for (int i = 0; i < pos - 1; i++){tmp = tmp->next;}// tmp at end node// init_node; malloc ,NULL,NULLDouLinkNode *newnode = malloc(sizeof(DouLinkNode));if (NULL == newnode){fprintf(stderr, "InsertTailDouLinkList malloc\n");return 1;}memcpy(&newnode->data, data, sizeof(DATATYPE));newnode->next = NULL;newnode->prev = NULL;newnode->next = tmp->next;newnode->prev = tmp;newnode->next->prev = newnode;tmp->next = newnode;dl->clen++;}return 0;
}//删除
int DeleteDouLinkList(DouLinkList *dl, char *name)
{DouLinkNode *tmp = FindDouLinkList(dl, name);if (NULL == tmp){printf("DeleteDouLinkList error\n");return 1;}if (tmp == dl->head){dl->head = dl->head->next;if (dl->head->prev){dl->head->prev = NULL;}}else  // mid end{if (tmp->next){tmp->next->prev = tmp->prev;}tmp->prev->next = tmp->next;}free(tmp);dl->clen--;return 0;
}//修改
int ModifyDouLinkList(DouLinkList *dl, char *name, DATATYPE *data)
{DouLinkNode *tmp = FindDouLinkList(dl, name);if (NULL == tmp){printf("modify failure...\n");return 1;}memcpy(&tmp->data, data, sizeof(DATATYPE));return 0;
}//查找
DouLinkNode *FindDouLinkList(DouLinkList *dl, char *name)
{DouLinkNode *tmp = dl->head;while (tmp){if (0 == strcmp(tmp->data.name, name)){return tmp;}tmp = tmp->next;}return NULL;
}




http://www.lryc.cn/news/588591.html

相关文章:

  • 微信小程序未登录状态下的导航拦截有哪些方法可以实现
  • 暑假Python基础整理 --异常处理及程序调试
  • python原生处理properties文件
  • 电动汽车制动系统及其工作原理
  • slam中的eskf观测矩阵推导
  • LangChain智能体开发实战:从零构建企业级AI助手
  • C++ Boost Aiso TCP 网络聊天(服务端客户端一体化)
  • CMake基础:覆盖项目开发的五大配套工具
  • 【机器学习深度学习】大模型推理速度与私有化部署的价值分析
  • ELK部署与使用详解
  • Docker部署语音转文字(STT)服务并接入Home Assistant
  • Dubbo高阶难题:异步转同步调用链上全局透传参数的丢失问题
  • 设备发出、接收数据帧的工作机制
  • HarmonyOS从入门到精通:动画设计与实现之九 - 实用动画案例详解(上)
  • HarmonyOS从入门到精通:动画设计与实现之九 - 实用动画案例详解(下)
  • 暑假Python基础整理 -- 文件及目录操作
  • keepalive模拟操作部署
  • 2025-7-14-C++ 学习 排序(2)
  • IoC容器深度解析:架构、原理与实现
  • 驱动开发系列60- Vulkan 驱动实现-SPIRV到HW指令的实现过程(1)
  • 分支战略论:Git版本森林中的生存法则
  • PHP password_verify() 函数
  • 什么是微服务?-核心思想:化整为零,各自为战
  • Node.js + Express的数据库AB View切换方案设计
  • 【EM算法】三硬币模型
  • 自动微分模块
  • Class9简洁实现
  • JavaScript进阶篇——第二章 高级特性核心
  • JavaScript进阶篇——第一章 作用域与垃圾回收机制
  • 力扣 hot100 Day44