简介:在双向链表中,我们可以通过任意一个结点访问到其前驱元素和后继元素,时间复杂度为O(1),所以双向链表是十分方便的,我们通常构建链表也会选择去构建双向链表。
单个节点包括两个指针:
空表的判断体条件是L->next == L 或者 L->prior == L
创建成功的链表:
那么如何创建这个链表呢?
提前构想好我们创建的链表是这样的:
不知道为什么插入Mermaid流程图是这样的,咱也不知道,咱也不敢问。总之重点是head头节点,我有意将它提出了循环。(当然头节点包含在链表里也可以)
#include<stdio.h>
#include<stdlib.h>
typedef struct circular_list
{
int data;
struct circular_list * piror;
struct circular_list * next;
}L;
//下面是创建链表
L * create(int n)
{
L * head = (L*)malloc(sizeof(L));
head->piror = head;
head->next = head;
L * fakehead = head;
L * p;
for (int i = 0; i < n; i++)
{
p = (L*)malloc(sizeof(L));
p->data = i;
fakehead->next = p;
p->next = head->next;
p->piror = fakehead;
head->next->piror = p;
fakehead = p;
}
return head;
}
void visit(L * head, int n)//循环了两遍来检测是否构成环
{
head = head->next;
printf("By the former to the later:\n");
for (int i = 0; i < 2 * n; i++)
{
printf("The data of the %dTH node is: %d\n",head->data+1,head->data);
head = head->next;
}
printf("Front to Back:\n");
for (int i = 0; i < 2 * n; i++)
{
printf("The data of the %dTH node is: %d\n", head->data + 1, head->data);
head = head->piror;
}
}
int main()
{
int n;
printf("The number of nodes that you want to create a linked list:");
scanf_s("%d", &n);
L * head = create(n);
visit(head, n);
return 0;
}
怎么删除双向循环链表里的节点呢?
这里延续使用上面的链表,删除节点的思路就是改变其前节点和后节点的piror和next,将这个节点“挤”出来,然后free。
//删除第m个节点
L * delete(L * head, int m)
{
L * p = head;
p = p->next;
for (int i = 1; i < m; i++)
{
p = p->next;
}
p->piror->next = p->next;
p->next->piror = p->piror;
free(p);
return head;
}
怎么往链表里添加节点呢?
一样的,添加节点就需要改变其前后节点的指针。
L * insert(L * head,int i)
{
L * p = head;
p = p->next;
for (int j = 1; j < i; j++)
{
p = p->next;
}
L * q = (L*)malloc(sizeof(L));
q->data = 521;
p->piror->next = q;
q->next = p;
q->piror = p->piror;
p->piror = q;
return head;
}
OK,就到这里啦。