#include <iostream>using namespace std;int main()
{typedef int ListType;typedef struct ListNode{ListType data;//无需写成指针类型,因为这是 每一个单个结点空间通过指针链接而成,而不是连续的内存空间struct ListNode *prev;struct ListNode *next;}ListNode;//创建一个新的结点:ListNode *BuyListNode(ListType x){ListNode *newnode = (ListNode *)malloc(sizeof (ListNode));//需要在 malloc 前面声明出结点的类型/*ListNode *prev = NULL; //已经malloc出了结点,无需再次重复创建ListNode *next = NULL;*/newnode->prev = NULL;newnode->next = NULL;newnode->data = x;return newnode;}//双向循环带头链表的初始化函数:(这里的初始化是对于每一个结点单独的初始化,此时需要单独的创建构成链表中的每一个结点)/*因为有哨兵位(头结点也是结点)的存在,*/ListNode *ListInit(){ListNode *head = BuySListNode(0);//这里的0属于链表结点数据域的初始值head->prev = head;//先将值初始化为自己本身head->next = head;return head;//初始化+创建了结点之后就需要返回这个结点的地址,不然无法与下一个结点进行链接}//双向带头循环链表的尾插:void ListPushBack(ListNode *head,ListType x){ListNode *newnode = BuySListNode(x);newnode->prev = head->prev;head->prev->next = newnode;//不要忘了插入最后一个结点后还要与整个链表的头结点重新进行链接newnode->next = head;head->prev = newnode;}//双向带头循环链表的头插/*特别注意:是在哨兵位之后第一个结点之前进行头插,而不是在哨兵位之前进行头插*/void ListPushHead(ListNode *head, ListType x){ListNode *newnode = BuyListNode(x);newnode->next = head->next;newnode->prev = head;head->next->prev = newnode;head->next = newnode;}//双向带头循环链表的尾删:void ListPopBack(ListNode *head){ListNode *tmp = head->prev->prev;free(head->prev);head->prev = tmp;tmp->next = head;}//双向带头循环链表的头删:/*同样需要注意:头删的不是哨兵位,而是哨兵位之后的第一个结点*/void ListPopHead(ListNode *head){assert(head);ListNode *tmp = head->next->next;//将哨兵位之后的第二个结点的地址进行存储free(head->next);head->next = tmp;tmp->prev = head;}//查找 带头双向循环 链表中的某一个结点(重要,易错)ListNode *FindListNode(ListNode *head, ListType x){assert(head);ListNode *cur = head->next;//跳过哨兵位从第一个结点开始遍历,因为哨兵位的数据域不存放值while (cur != head)/*遍历的条件应该以第一个结点是否到达最后一个结点,然后在循环体内部判断每一次遍历到的结点中的数据域是否满足条件;而不是直接在while的条件判断中以每一个结点的数据域是否等于给定值,因为这样只能在结束循环体时才能拿到对应的结点,而循环的结束也有可能是因为没有找到结点,而遍历结束的原因;虽然也可通过中间变量记录,但不太整洁*/{if (cur->data == x){return cur;}else{cur = ccur->next;}}return NULL;//while循环结束后还没有找到}//对 带头双向循环 链表的其中一个结点(给定函数该结点的地址)进行删除的函数:/*注意:因为是对链表中任意一个结点的删除,所以头删,与尾删都可以复用该函数。*/void ListErase(ListNode *pos){assert(pos);ListNode *tmp = pos->prev;tmp->next = pos->next;pos->next->prev = tmp;free(pos);pos = NULL;}//将带头循环双向链表的其中一个结点地址传入实现“任意结点前插入”的函数:/*同理:有了任意位置插入元素函数的实现,我们的头插、尾插函数便可以复用这个函数来实现*/void ListInsert(ListNode *pos,ListType x){assert(pos);ListNode *tmp = pos->prev;ListNode *newnode = BuyListNode(x);tmp->next = newnode;pos->prev = newnode;newnode->next = pos;newnode->prev = tmp;}//判断 带头双向循环链表 是否为空的函数:bool ListEmpty(ListNode *head){if (head->next == NULL){return false;}else{return true;}}//统计 带头双向循环链表 中有效结点的个数int ListNodeSize(ListNode *head){assert(head);ListNode *cur = head->next;int num = 0;while (cur != head){num++;cur = cur->next;}return num;}//对整个链表进行销毁操作的函数/*不要忘了最后也要将头结点释放*/void ListDestroy(ListNode *head){assert(head);ListNode *cur = head->next;while (cur != head){ListNode *tmp = cur->next;//释放当前结点时要将下一个结点提前存储用于下一个结点的遍历和释放free(cur);cur = tmp;}free(head);head = NULL;}}

【数据结构】带头+双向+循环链表的 增,删,查,改 的实现相关推荐

  1. 数据结构-带头双向循环链表(增删查改详解)

    在上一篇博客中,详细介绍了单链表的增删查改,虽然单链表的结构简单,但是用起来却不是那么顺手.因此根据单链表的种种缺点,这篇博客所介绍的带头双向循环链表将会带来极大的优化. 上图就是带头双向循环链表的主 ...

  2. java 增 删 查 改_如何对java链表进行增、删、查、改操作

    如何对java链表进行增.删.查.改操作 发布时间:2020-06-23 10:41:33 来源:亿速云 阅读:79 作者:Leah 如何对java链表进行增.删.查.改操作?针对这个问题,今天小编总 ...

  3. 【数据结构】带头+双向+循环链表(增、删、查、改)的实现_【附源码、图片示例】_ [初阶篇_ 复习专用]

  4. 实现简单的带头双向循环链表

    双向链表 1. 带头双向循环链表的定义 2. 带头双向循环链表的创建 3. 带头双向循环链表的增删改查 (1)头插头删 (2)尾插尾删 (3)pos位置的前插与删除 4.插入与删除改良 1. 带头双向 ...

  5. 初阶数据结构之带头+双向+循环链表增删查实现(三)

    文章目录 @[TOC](文章目录) 前言 一.带头双向循环链表的初始化 1.1带头双向循环链表的结构体定义 1.2初始化代码的实现 二.带头+双向+循环链表的增功能实现 2.1头插代码的实现 2.2尾 ...

  6. 【数据结构】链表:带头双向循环链表的增删查改

    本篇要分享的内容是带头双向链表,以下为本片目录 目录 一.链表的所有结构 二.带头双向链表 2.1尾部插入 2.2哨兵位的初始化 2.3头部插入 2.4 打印链表 2.5尾部删除 2.6头部删除 2. ...

  7. 【数据结构】-关于带头双向循环链表的增删查改

    作者:低调 作者宣言:写好每一篇博客 文章目录 前言 一.带头双向循环链表的实现 1.1创建返回链表的头结点 1.2开辟一个新的结点 1.3双向链表的销毁 1.4双向链表的打印 1.5双向链表尾插 1 ...

  8. 【数据结构】带头双向循环链表的增删查改(C语言实现)

    文章目录 前言 一.什么是带头双向循环链表 二.带头双向循环链表的实现 1.结构的定义 2.链表的初始化 3.开辟新节点 4.在头部插入数据 5.在尾部插入数据 6.查找数据 7.在pos位置之前插入 ...

  9. 【数据结构初阶】链表(下)——带头双向循环链表的实现

    目录 带头双向循环链表的实现 1.带头双向循环链表的节点类型 2.创建带头双向循环链表的节点 3.向带头双向循环链表中插入数据 <3.1>从链表尾部插入数据 <3.2>从链表头 ...

最新文章

  1. 曙光i620c20用户手册_曙光天阔I620-G20服务器技术白皮书.pdf
  2. 11.4 上限分析-机器学习笔记-斯坦福吴恩达教授
  3. antd listView中onEndReached()失效
  4. getContext() , getApplicationContext() , getBaseContext() and “this”的区别
  5. Python中的枚举(enumerate)
  6. 使用wordpress分页函数paginate_links
  7. PhpStorm连接docker容器内的php XDebug进行断点调试
  8. php并发访问排队_使用xdebug对php做性能分析调优
  9. google datastudio 使用教程
  10. Delphi10.4.1开发Linux应用视频重播
  11. H3CSE园区-IRF
  12. 在全志平台调试博通的wifi驱动(类似ap6212)
  13. phpStorm和git解决冲突
  14. 项目创新特色概述及主要内容
  15. Adobe read X安装过程中出现无法将数值DisableExceptionChainValidation写入键
  16. 计算机网络不同层中用于将网络互连的中间设备——转发器、网桥(桥接器)、路由器、网关
  17. 计算机管理的磁盘管理简单卷,小编教你磁盘管理新建简单卷怎么做
  18. 03-jQuery事件绑定和解绑
  19. SPSS统计教程:判断数据正态分布的超多方法!
  20. Curl学习日记2 - 在Windows CMD命令行中使用Curl

热门文章

  1. zeppelin重启
  2. STM32老人防跌倒报警GSM短信GPS定位设计(程序+原理图+PCB)
  3. 线上自用防伪系统源码,可以商用,后端java,前端uni-app
  4. 对不起你现在真的不能打了
  5. 湖北十堰普降大雪 武当山景区暂停售票
  6. maven报错Non-resolvable parent POM for “项目名称“:1.0-SNAPSHOT: Could not find artifact pom:1.0-SNAPSHOT
  7. 只知道spring?Java的前世今生了解一下
  8. 电控相关公式以及参数(转载整合)
  9. Tire树 Java实现
  10. iodine_Iodine消除了一些限制Java开发人员的限制