带头循环双链表(跑路人笔记)

简介: 带头循环双链表(跑路人笔记)

前言

带头双向循环链表的结构方便且易实现,值得一搞😎

结构体类型如下🤪

typedef int LTDataType;
typedef struct ListNode
{
  struct ListNode* next;
  struct ListNode* prev;
  LTDataType data;
}ListNode;

结构体的类型用typedef进行重命名这样方便未来的数据更改,(不用#define, 类型的重命名使用typedfe)

next指针指向下一位空间,prev指向上一处空间.末尾的next指向哨兵位哨兵位的prev指向末尾.

ListInit🐱‍🐉

ListNode* BuyListNode(LTDataType x)
{
  ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
  newnode->data = x;
  newnode->next = NULL;
  newnode->prev = NULL;
  return newnode;
}
ListNode* ListInit()
{
  ListNode* phead = BuyListNode(0);
  phead->next = phead;
  phead->prev = phead;
  return phead;
}
  • 带头循环链表的哨兵位的值应该是无意义的值不然后续更改数据类型可能会有警告或其他麻烦.
  • 上方BuyListNode后面的前插和后插还会使用所以干脆直接将其封装成一个函数.
  • 开始无数据时的哨兵位自己指向自己.

如图:

image.png

ListDestory✌

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

将链表全部毁灭(释放)

ListPrint设置标签

void ListPrint(ListNode* phead)
{
  assert(phead);
  ListNode* cur = phead->next;
  while (cur != phead)
  {
    printf("%d ", cur->data);
    cur = cur->next;
  }
  printf("\n");
}

打印链表数值,更多为了方便调试和观察代码错误=-=.

ListPushBack🤪

void ListPushBack(ListNode* phead, LTDataType x)
{
  assert(phead);
  ListNode* tail = phead->prev;
  ListNode* newnode = BuyListNode(x);
  tail->next = newnode;
  newnode->prev = tail;
  newnode->next = phead;
  phead->prev = newnode;
}

phead在为初始化时为NULL通过断言我们可以将未初始化的phead排除

尾插,为了方便思考我们将tail(尾部)单独创建变量保存

image.png

我们只需实现上图功能就好

ListPushFront

void ListPushFront(ListNode* phead, LTDataType x)
{
  assert(phead);
  ListNode* first = phead->next;
  ListNode* newnode = BuyListNode(x);
  // phead newnode first
  phead->next = newnode;
  newnode->prev = phead;
  newnode->next = first;
  first->prev = newnode;
}

前插, 前插重要的是第一次插入时将phead的prev指向末尾,但是我们这个结构妙就妙在可以轻松解决这个问题我们的first在刚开始的时候他的值和phead相同,因为在刚开始phead的next和prev都指向phead.

所以在修改first->prev的时候直接就将phead的prev指向新内容在后续开辟时phead的prev不受改变一直指向最后的那块空间.


ListPopBack

void ListPopBack(ListNode* phead)
{
  assert(phead);
  assert(phead->next != phead);
  ListNode* tail = phead->prev;
  ListNode* prev = tail->prev;
  prev->next = phead;
  phead->prev = prev;
  free(tail);
  tail = NULL;
  ListErase(phead->prev);
}


后删从后面开始删除,没啥难点=-=.


ListPopFront


void ListPopFront(ListNode* phead)
{
  assert(phead->next != phead);
  ListNode* first = phead->next;
  ListNode* second = first->next;
  phead->next = second;
  second->prev = phead;
  free(first);
  first = NULL;
}


前删没难点=-=.


ListFind

ListNode* ListFind(ListNode* phead, LTDataType x)
{
  assert(phead);
  ListNode* cur = phead->next;
  while (cur != phead)
  {
  if (cur->data == x)
  {
    return cur;
  }
  cur = cur->next;
  }
  return NULL;
}



寻找x数据的空间并返回地址,找不到则返回空


ListInsert

// pos位置之前插入x
void ListInsert(ListNode* pos, LTDataType x)
{
  assert(pos);
  ListNode* prev = pos->prev;
  ListNode* newnode = BuyListNode(x);
  // prev newnode pos
  prev->next = newnode;
  newnode->prev = prev;
  newnode->next = pos;
  pos->prev = newnode;
}



和上面的函数对应起来由上面函数查找的值判断非空后使用该函数插入.


ListErase

// 删除pos位置的值
void ListErase(ListNode* pos)
{
  assert(pos);
  ListNode* prev = pos->prev;
  ListNode* next = pos->next;
  prev->next = next;
  next->prev = prev;
  free(pos);
}



结尾

求个点赞,我也想要机器人粉丝😭


相关文章
|
3月前
|
存储 缓存 程序员
手撕【双向链表】带头双向循环(2)
手撕【双向链表】带头双向循环(2)
20 0
|
4月前
|
Python Go Java
Golang每日一练(leetDay0042) 二叉树最大路径和、回文串、单词接龙II
Golang每日一练(leetDay0042) 二叉树最大路径和、回文串、单词接龙II
31 0
Golang每日一练(leetDay0042) 二叉树最大路径和、回文串、单词接龙II
|
4月前
|
Python C++ Java
C/C++每日一练(20230405) 数组元素循环右移、输出字符图形、移除链表元素
C/C++每日一练(20230405) 数组元素循环右移、输出字符图形、移除链表元素
21 0
C/C++每日一练(20230405) 数组元素循环右移、输出字符图形、移除链表元素
|
9月前
|
存储
带头循环双向链表详解 1
带头循环双向链表详解
图文版实现无头非循环单链表的增加和删除操作
图文版实现无头非循环单链表的增加和删除操作
不带头非循环的单向链表的增删查改的实现(代码版)
不带头非循环的单向链表的增删查改的实现(代码版)
|
5月前
|
存储 算法
数据结构单链表之检测和删除链表中的循环 | 第十三套
数据结构单链表之检测和删除链表中的循环 | 第十三套
30 0
|
6月前
|
存储 C++
【双向链表】带头双向循环(1)
【双向链表】带头双向循环(1)
48 0
|
7月前
|
存储 缓存 算法
【算法基础】数组和链表,动态数组,循环数组,链表的变种
【算法基础】数组和链表,动态数组,循环数组,链表的变种
45 0
|
7月前
链表翻转循环和递归写法(画图分析)
链表翻转循环和递归写法(画图分析)
20 0