带头双向循环链表

简介: 带头双向循环链表

概述


带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。


双向循环链表含有一个头节点(哨兵位),含有两个指针域,next,prev,分别指向节点的后继和前驱。需要注意的是,头节点的prev指向尾节点,尾节点的next指向头节点

看着复杂,实际操作起来很简单。


初始化


和单链表初始化差不多,无非就是多了一个prev指针

LTNode* CreateLTNode(LTDataType x)
{
  LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
  if (newnode == NULL)
  {
    perror("malloc fail");
    exit(-1);
  }
  newnode->val = x;
  newnode->next = NULL;
  newnode->prev = NULL;
  return newnode;
}
LTNode* LTInit()
{
  LTNode* phead = CreateLTNode(-1);
  phead->next = phead;
  phead->prev = phead;
  return phead;
}


销毁


遍历链表,并定义一个next 来保存 cur 的下一个节点,在链表都free 完后,再销毁头节点;

注意:应该是从头节点的 next 开始遍历。

void ListNodedestroy(LNode* phead)
{
  assert(phead);
  LNode* cur = phead->next;
  while (cur != phead)
  {
    LNode* next = cur->next;
    free(cur);
    cur = next;
  }
  free(phead);
  phead = NULL;
}


插入


找到 pos 的前驱 prev ;

将前驱,pos,新节点链接起来。

void LTInsert(LTNode* pos, LTDataType x)
{
  assert(pos);
  LTNode* posPrev = pos->prev;
  LTNode* newnode = CreateLTNode(x);
  // posprev newnode pos
  posPrev->next = newnode;
  newnode->prev = posPrev;
  newnode->next = pos;
  pos->prev = newnode;
}


删除


找到 pos 的前驱和后继;

链接其前驱,后继;

删除pos。

void LTErase(LTNode* pos)
{
  assert(pos);
  LTNode* posNext = pos->next;
  LTNode* posPrev = pos->prev;
  posPrev->next = posNext;
  posNext->prev = posPrev;
  free(pos);
  //pos = NULL;
}


遍历打印


void LTPrint(LTNode* phead)
{
  assert(phead);
  printf("哨兵位<=>");
  LTNode* cur = phead->next;
  while (cur != phead)
  {
    printf("%d<=>", cur->val);
    cur = cur->next;
  }
  printf("\n");
}
目录
相关文章
|
存储 负载均衡 网络协议
看完就会使用Nacos-服务发现
看完就会使用Nacos-服务发现
572 0
|
5月前
|
弹性计算 安全 Linux
2026年新手小白租用阿里云服务器全流程步骤(手把手教程)
对于首次接触云服务器的新手来说,租用流程可能略显复杂。以阿里云为例,其提供多种服务器类型与配置选项,适配不同需求。下面用通俗语言拆解从注册到完成租用的全步骤,结合最新配置细节与价格参考,帮助快速拥有专属云服务器。
|
3月前
|
人工智能 安全 机器人
保姆级教程:OpenClaw部署步骤(阿里云/Win11/MacOS/Linux)+大模型智谱/百炼API配置+钉钉集成+FAQ
“想拥有完全掌控数据隐私的AI助手,却卡在部署环节?”——这是2026年众多技术爱好者的共同困扰。OpenClaw作为开源本地AI助手的标杆,支持在个人服务器或本地设备部署,通过钉钉、飞书等聊天工具交互,可执行系统命令、管理文件、编写代码,甚至对接图片识别/生成功能,核心优势在于“数据私有化+功能全自定义”。
1310 7
|
8月前
|
边缘计算 运维 监控
云管平台(CMP)介绍及厂商推荐
云管平台(CMP)是企业多云、混合云管理的核心工具,实现资源统一调度、自动化运维、成本优化与安全合规。支持多云整合、智能监控、云原生及边缘计算,提升管理效率,降低运营成本,助力企业数字化转型。佳杰云星CMP支持主流云厂商,提供免费社区版。
|
Linux C语言 Python
perf_event_open 学习 —— 通过read的方式读取硬件技术器
perf_event_open 学习 —— 通过read的方式读取硬件技术器
|
存储 IDE Go
怎样使用gofmt格式化代码
**gofmt**是Go语言官方的代码格式化工具,确保代码遵循统一风格。它能读取标准输入或格式化指定文件及目录中的.go文件。使用`-s`参数可以简化代码,例如移除不必要的类型声明、索引指定和变量赋值。`-w`参数将格式化结果写回源文件。`go fmt`是`gofmt`的简单封装,通常带有`-l -w`参数。在Goland中,可通过设置File Watcher自动调用gofmt进行格式化。
304 4
|
监控 关系型数据库 MySQL
Flink CDC产品常见问题之look up hint 没有生效如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
1487 1
|
数据采集 Python
Python多线程与异步IO的对比:何时选择哪种并发模型
Python多线程与异步IO的对比:何时选择哪种并发模型
1068 1
段落标记<p>的对齐属性
【8月更文挑战第30天】段落标记<p>的对齐属性
265 0
|
JavaScript
js左划出现删除按钮,右滑隐藏demo效果示例(整理)
js左划出现删除按钮,右滑隐藏demo效果示例(整理)
js左划出现删除按钮,右滑隐藏demo效果示例(整理)