双向循环链表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向循环链表相关的知识,希望对你有一定的参考价值。
循环双向链表如下图所示:
大家通过图来看与循环单链表基本是一样,代码的套路也基本一样,除了每个节点都多一个前驱。
很多和我一样的初学者都很困惑,单链表,双链表,还有循环链表为什么搞那么复杂,很简单因为需求。
学编程你不得不时刻容纳新知识,很多人没有去深入去学习,就像没有驱动一样。有单向就有双向,有双向就有循环,更多的需求让大家进步,就像人不懂得满足。
有些人问我,为什么别人能够把代码逻辑写的清晰,为什么如何别人能够那么优秀,很多人说:练习的多,敲代码量大,不得不否认确实有这方面因素,但是我认为思考更为重要。大量的思考让这些编程员中脑子可以浮动出任何的算法与数据结构,这也许才是真正的灵魂。
扯远了,再来一张构造双向链表的图,因为与单链表不同,所以格外做了一张图让刚学习的朋友们删除等参考,分享更多的知识。
代码如下:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
struct Node *prior;
}Node,*PNode;
void ControlLinkList(PNode PHead); //控制函数
PNode CreateLinkList(void); //构造双向循环链表
int PositionLinkList(PNode PHead); //正向遍历
void ReverseLinkList(PNode PHead); //逆向遍历
void InsertLinkList(PNode PHead, int pos, int len); //插入某节点
void DeleteLinkList(PNode PHead, int pos); //删除某节点
void FindDLinkList(PNode PHead, int pos); //查询某节点
void ReleaseLinkList(PNode PHead); //释放链表
void ReversesLinkList(PNode PHaed); //反转链表--对于循环双向链表反转没有太大意义
int main(void)
{
PNode PHead = CreateLinkList();
ControlLinkList(PHead);
return 0;
}
PNode CreateLinkList(void)
{
int len = 0;
int i;
PNode PHead = (PNode)malloc(sizeof(Node));
PNode r;
if( NULL == PHead )
{
printf("分配内存失败
");
exit(EXIT_FAILURE);
}
//初始化头
PHead->data = 0;
PHead->prior = PHead;
PHead->next = PHead;
r = PHead;
printf("请输入构造几个节点: ");
scanf("%d",&len);
for( i = 0; i < len; i++ )
{
PNode p = (PNode)malloc(sizeof(Node));
if( NULL == p )
{
printf("分配内存失败
");
exit(EXIT_FAILURE);
}
printf("Please input of data: ");
scanf("%d",&p->data);
p->next = NULL; //后驱为NULL
p->prior = r; //前驱指向r也就是PHead头节点
r->next = p; //然后r的后驱也就PHead的后驱指向p
r = p; //最后r = p;
}
r->next = PHead;
PHead->prior = r; //这两步完成了链表循环,头尾想指
return PHead; //循环双向链表返回头指针既可以正向反向遍历
}
int PositionLinkList(PNode PHead)
{
int i = 0;
PNode p = PHead->next; //PHead->next才是链表第一个元素
while( NULL != p && PHead != p )
{
i++;
printf("No.%d of Data = %d
",i,p->data);
p = p->next;
}
printf("正向遍历成功");
return i;
}
void ReverseLinkList(PNode PHead)
{
int i = 0;
PNode p = PHead->prior; //指向了链表尾部r
while( NULL != p && p != PHead )
{
i++;
printf("No.%d of Data = %d
",i,p->data);
p = p->prior;
}
printf("逆向遍历成功
");
}
void InsertLinkList(PNode PHead, int pos, int data)
{
int i = 1;
PNode p = PHead->next;
PNode PNew = (PNode)malloc(sizeof(Node));
if( NULL == p )
{
printf("内存分配失败
");
exit(EXIT_FAILURE);
}
while( p != NULL && i != pos-1 )
{
i++;
p = p->next;
}
PNew->data = data;
p->next->prior = PNew;
PNew->next = p->next;
p->next = PNew;
PNew->prior = p;
printf("插入成功
");
}
void FindLinkList(PNode PHead, int pos)
{
PNode p = PHead->next;
int i = 1;
while( NULL !=p && i != pos )
{
i++;
p = p->next;
}
printf("No.%d of Data = %d
", i, p->data);
}
void DeleteLinkList(PNode PHead, int pos)
{
int i = 1;
PNode p = PHead->next;
PNode temp;
while( NULL !=p && i != pos )
{
i++;
p = p->next;
}
temp = p->next; //temp指向删除的节点
p->next = p->next->next; //p->next节点指向删除节点的next
p->next->next->prior = p;
free(temp);
printf("删除节点成功
");
}
void ReleaseLinkList(PNode PHead)
{
PNode p,q;
p = PHead;
q = p->next;
while( q != PHead )
{
p = q;
q = p->next;
free(p);
}
free(PHead);
printf("释放内存成功");
}
void ControlLinkList(PNode PHead)
{
int len = 0;
int pos = 0;
len = PositionLinkList(PHead);
ReverseLinkList(PHead);
printf("请输入pos节点: ");
scanf("%d",&pos);
InsertLinkList(PHead, pos, 10);
PositionLinkList(PHead);
printf("请输入查询的节点: ");
scanf("%d",&pos);
FindLinkList(PHead, pos);
printf("请输入删除的节点: ");
scanf("%d",&pos);
DeleteLinkList(PHead, pos);
PositionLinkList(PHead);
ReleaseLinkList(PHead);
}
以上是关于双向循环链表的主要内容,如果未能解决你的问题,请参考以下文章