数据结构——线性表的链式存储结构3(双向循环链表)

简介: 数据结构——线性表的链式存储结构3(双向循环链表)

目录

前言

定义

双向循环链表的构建

双向循环链表的初始化

新节点的创建

双向循环链表的尾插

双向循环链表的头插

双向循环链表数据的逐一打印

双向循环链表的尾删

双向循环链表的头删

双向循环链表某数据位置的查找

双向循环链表任意位置的插入

双向循环链表任意位置的删除

前言

在之前讲的链表中,有了头结点时,我们可以用O(1)的时间访问第一个结点,但对于要访问到最后一个结点,却需要O(n)的时间,因此出现了双向链表。

定义

在单链表的每个结点中,在设置一个指向其前驱结点的指针域,最后一个结点又指向头结点,头节点的前驱指针指向最后一个结点,从而构成一个回路。

image.png

双向循环链表的构建

typedef int LTDatype;
typedef struct ListNode
{ 
  struct ListNode* next;//后驱指针
  struct ListNode* prev;//前驱指针
  LTDatype data;
}ListNode;

双向循环链表的初始化

ListNode* ListInit(void)
{
  ListNode* phead = BuyListNode(0);
  phead->next = phead;
  phead->prev = phead;
  return phead;
}

初始化后

image.png

新节点的创建

ListNode* BuyListNode(LTDatype x)
{
  ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
  newnode->data = x;
  newnode->next = NULL;
  newnode->prev = NULL; 
  return newnode;
}

双向循环链表的尾插

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

双向循环链表的头插

void pushfront(ListNode* phead,LTDatype x)
{
  assert(phead);
  ListNode* newnode = BuyListNode(0);
  ListNode* first = phead->next;
  newnode->data = x;
  newnode->next = first;
  newnode->prev = phead;
  first->prev = newnode;
  phead->next = newnode;
}

双向循环链表数据的逐一打印

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

双向循环链表的尾删

void popback(ListNode* phead)
{
  assert(phead);
  assert(phead->next != phead);
  ListNode* tail = phead->prev;
  ListNode* tail2 = tail->prev;
  phead->prev = tail2;
  tail2->next = phead;
  free(tail);
}

双向循环链表的头删

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

双向循环链表某数据位置的查找

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

双向循环链表任意位置的插入

void ListInsert(ListNode* pos, LTDatype x)
{
  assert(pos);
  ListNode* prev = pos->prev;
  ListNode* newnode = BuyListNode(0);
  newnode->data = x;
  newnode->next = pos;
  prev->next = newnode;
  newnode->prev = prev;
  pos->prev = newnode;
}

双向循环链表任意位置的删除

void ListErase(ListNode* pos)
{
  assert(pos);
  ListNode* next = pos->next;
  ListNode* prev = pos->prev;
  next->prev = prev;
  prev->next = next;
  free(pos);
}
相关文章
|
14天前
|
存储
数据结构第二课 -----线性表之单向链表
数据结构第二课 -----线性表之单向链表
|
5天前
|
存储 算法 Java
数据结构与算法 数组和链表
数据结构与算法 数组和链表
11 0
|
5天前
|
存储 Java
深入浅出数据结构之链表
深入浅出数据结构之链表
|
5天前
|
C++
数据结构(双链表
数据结构(双链表
8 1
|
8天前
|
存储 缓存
[数据结构]~双向+循环链表从(0~1)
[数据结构]~双向+循环链表从(0~1)
|
7天前
|
机器学习/深度学习 算法 测试技术
【单调栈】3113. 边界元素是最大值的子数组数目
【单调栈】3113. 边界元素是最大值的子数组数目
|
1天前
|
存储 NoSQL C语言
数据结构——顺序栈与链式栈的实现-2
数据结构——顺序栈与链式栈的实现
数据结构——顺序栈与链式栈的实现-2
|
1天前
|
存储 C语言
数据结构——顺序栈与链式栈的实现-1
数据结构——顺序栈与链式栈的实现
数据结构——顺序栈与链式栈的实现-1
|
5天前
栈的基本应用
栈的基本应用
11 3
|
5天前
栈与队列理解
栈与队列理解
12 1