循环双向链表以下图所示:
你们经过图来看与循环单链表基本是同样,代码的套路也基本同样,除了每一个节点都多一个前驱。
不少和我同样的初学者都很困惑,单链表,双链表,还有循环链表为何搞那么复杂,很简单由于需求。
学编程你不得不时刻容纳新知识,不少人没有去深刻去学习,就像没有驱动同样。有单向就有双向,有双向就有循环,更多的需求让你们进步,就像人不懂得知足。
有些人问我,为何别人可以把代码逻辑写的清晰,为何如何别人可以那么优秀,不少人说:练习的多,敲代码量大,不得不否定确实有这方面因素,可是我认为思考更为重要。大量的思考让这些编程员中脑子能够浮动出任何的算法与数据结构,这也许才是真正的灵魂。
扯远了,再来一张构造双向链表的图,由于与单链表不一样,因此格外作了一张图让刚学习的朋友们删除等参考,分享更多的知识。算法
代码以下:编程
#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("分配内存失败\n"); 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("分配内存失败\n"); 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\n",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\n",i,p->data); p = p->prior; } printf("逆向遍历成功\n"); } 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("内存分配失败\n"); 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("插入成功\n"); } 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\n", 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("删除节点成功\n"); } 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); }