文章目录

  • 先看看头文件
  • 初始化和创建节点
  • 尾插/尾删
  • 头插和头删
  • 查找pos
  • 删除pos位置的节点
  • 在pos位置前插入元素

先看看头文件

根据头文件来写出各个函数


#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int LTDataType;typedef struct ListNode
{LTDataType data;struct ListNode* next;struct ListNode* pre;
}ListNode;//初始化
ListNode* InitListNode();//创建一个节点
ListNode* BuyListNode(LTDataType x);//尾插
void ListPushBack(ListNode* phead,LTDataType x);
//尾删
void ListPopBack(ListNode* phead);//头插
void ListPushFront(ListNode* phead,LTDataType x);
//头删
void ListPopFront(ListNode* phead);//查找
ListNode* ListFind(ListNode* phead, LTDataType x);//删除pos位置的值
void ListErase(ListNode* phead, ListNode* pos);//在pos位置前添加元素
void ListInsertFront(ListNode* phead, ListNode* pos, LTDataType x);//打印
void Listprint(ListNode* phead);

看完之后大家之后肯定有一个疑惑?这个头插头删尾插尾删为什么传的都是一级指针?
这里涉及的是带头(带哨兵位)和不带头两种情况
看图的解释:

初始化和创建节点

ListNode* BuyListNode(LTDataType x)
{ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));if (newnode == NULL){printf("创建节点失败\n");exit(-1);}newnode->data = x;newnode->next = NULL;newnode->pre = NULL;return newnode;
}ListNode* InitListNode()
{ListNode* phead = BuyListNode(0);phead->next = phead;   phead->pre = phead;return phead;
}

只有头(初始化)

尾插/尾删

void ListPushBack(ListNode* phead, LTDataType x)
{ListNode* newnode = BuyListNode(x);ListNode* tail = phead->pre;  //找到尾tail->next = newnode;       //先连接尾和newnodenewnode->pre = tail;  newnode->next = phead;     //在连接头和newndoephead->pre = newnode;
}
void ListPopBack(ListNode* phead)
{assert(phead);if (phead->next == phead){printf("没有节点可以删除\n");return;}ListNode* tail = phead->pre;  //找尾ListNode* pretail = tail->pre;  //找尾的前一个pretail->next = phead;    /将尾的前一个和头连接phead->pre = pretail;free(tail);
}

头插和头删

void ListPushFront(ListNode* phead, LTDataType x)
{//头插assert(phead);ListNode* newnode = BuyListNode(x);ListNode* save = phead->next;  //保存还没插入时的第一个节点newnode->next = save;     //要插入的接点和第一个连接save->pre = newnode;phead->next = newnode;   //要插入的节点和头连接newnode->pre = phead;}void ListPopFront(ListNode* phead)
{assert(phead);if (phead->next == phead){printf("没有可以的删除的元素啦\n");return;}ListNode* save = phead->next;  //第一个节点,要删除的节点phead->next = save->next;   //连接头和第二个节点==》》就是删除第一个节点save->next->pre = phead;free(save);
}

查找pos

ListNode* ListFind(ListNode* phead, LTDataType x)
{assert(phead);ListNode* cur = phead->next;while (cur != phead)   //cur等于头的时候就是找完了{if (cur->data == x)return cur;cur = cur->next;}printf("找不到\n");
}

删除pos位置的节点

void ListErase(ListNode* phead, ListNode* pos)
{assert(phead && pos);ListNode* prepos = pos->pre;   //记录pos位置的前一个和后一个节点ListNode* nextpos = pos->next;prepos->next = nextpos;   //将pos的前一个和后一个连接---》》就是删除pos了nextpos->pre = prepos;free(pos);
}

在pos位置前插入元素

void ListInsertFront(ListNode* phead, ListNode* pos, LTDataType x)
{assert(phead && pos);ListNode* newnode = BuyListNode(x);ListNode* prepos = pos->pre;    //记录一下pos前一个节点newnode->next = pos;      //连接要插入的节点和pos位置的节点pos->pre = newnode;prepos->next = newnode;    //连接要插入的和pos前一个节点newnode->pre = prepos;
}

双向-带头--循环链表相关推荐

  1. 【数据结构初阶】双向带头循环链表原来是纸老虎,结构复杂,操作简单

    目录 0.结构体定义 1.初始化 2.尾插 3.打印 4.头插 5.任意位置插入前面位置 6.尾删 7.头删 8.链表长度 9.任意位置删除当前位置 10. 销毁 双向带头循环链表:结构复杂,操作简单 ...

  2. 链表界的“扛把子”—双向带头循环链表

    目录 一:链表的分类 二:链表的实现 2-1:创建链表 2-2:创建新的结点 2-3:初始化链表 2-4:打印链表 2-5:销毁链表 三:链表的核心功能 3-1:尾插 3-2:尾删 3-3:链表查找 ...

  3. 双向带头循环链表的(增删查改)的实现

    文章目录 一.双向带头循环链表 构成 二.双向带头循环链表的实现 1.函数的定义和结构体的创建--list.h 2.函数的调用--list.c 3. 双向带头循环链表与单链表的传递参数区别 4.双向带 ...

  4. 数据结构------双向带头循环链表

    目录 1.什么是双向带头循环链表?模型. 2.1 创建结点函数 2.2初始化 3.尾插实现 3.1图示 3.2尾插 4.打印函数实现 4.1打印函数 5.思考为啥是一级指针 6.头插实现 6.2实现代 ...

  5. 双向带头循环链表的实现

    双向带头循环链表 双向带头循环链表 结构讲解 期望实现功能 创建链表和头节点作用 头插和头删 头插 头删 尾插与尾删 尾插 尾删 pos 删除和插入 插入 删除 打印和查找 整体代码 这个数据结构可以 ...

  6. 外强中干——双向带头循环链表

    前言:众所周知,链表有八种结构,由单向或双向,有头或无头,循环或不循环构成.在本篇,将介绍8种链表结构中最复杂的--双向带头循环链表.听着名字或许挺唬人的,但实际上双向带头循环链表实现起来比结构最简单 ...

  7. 【双向带头循环链表】

    双向带头循环链表 0.链表中每个节点的基本结构 1.初始化链表(创建哨兵位头节点) 2.申请新节点 3.尾插节点 4.尾删节点 5.头插节点 6.头删节点 7.寻找pos位置的节点 8.在pos位置之 ...

  8. 双向带头循环链表-实现思路+图解

    目录 一.何为双向循环链表? 1.何为'双向'? 2.何为'带头'? 3.何为'循环'? 二.如何实现双向带头循环链表? 1.基本结构-结点的创建 2.创建哨兵位结点 3.链表的增删查改 一.何为双向 ...

  9. 双向带头循环链表详解

    在上一篇所讲述的 单链表 中,存在一些缺陷: 1.在进行尾插和尾删时,需要遍历链表找到尾结点 2.在进行中间插入和删除时,也需要先遍历链表找到前一个结点 对于这些缺陷,可以采用一种结构更为复杂的链表 ...

  10. 【数据结构--双向带头循环链表(链表中的老大哥)】

    双向带头循环链表及相关OJ

最新文章

  1. 2018年中美自动驾驶进展分析报告
  2. javascript中的异步 macrotask 和 microtask 简介
  3. 《C++ Primer 4th》读书笔记 第6章-语句
  4. 视窗宽高offset、client、scroll
  5. python的自定义异常类,带参Exception,多个except,断言语句,断点,try...except,try...except...else,try...except...finally处理
  6. 蓝桥杯2018年第九届C/C++省赛B组第一题-第几天
  7. 设计模式---责任链模式(C++实现)
  8. 深入浅出MFC:《深入浅出MFC》入手基础指南
  9. java职业规划怎么写_java个人职业生涯发展规划书范文
  10. html中加入标题居中,在html标题标记中居中的div元素
  11. RTI -- 实时中断
  12. gis地图图层(前台)
  13. Longhorn 企业级云原生分布式容器存储-券(Volume)和节点(Node)
  14. 计算机三级上机场,自学通过计算机二级、三级、四级,保研天津大学,证书拿到手软!你被中航大男神圈粉了吗?...
  15. 隔壁住着一个过气的明星是什么体验?
  16. 同样协调个事情,为什么有人一说就通,有人一说就炸?(转,知乎)
  17. 一口气笑穿极简印度史,简到崩溃,笑到流泪(一)
  18. 7.2 - 在线教育平台系统
  19. 微尘,心中的那一抹思念
  20. ZJOI2019一轮停课刷题记录

热门文章

  1. 解决python编码格式错误问题
  2. 用for循环求1~10所有偶数的和并显示奇数偶数
  3. 2020年最新flag大赏(紧急修订版)
  4. Android——超简单 MVC、MVP、MVVM入门系列
  5. Ubuntu连接投影仪时,分辨率不匹配引起的错误
  6. 这才是成年人最崩溃的时刻
  7. 鼠标左键双击变成打开“属性”,其他按键失灵
  8. 看了功夫熊猫,非常不错。
  9. Android开发(4):个人信息修改个人信息,修改头像设计
  10. java氧气版_java – 为什么不开始吸氧(第一次)?