简要介绍
循环双链表是一种特殊的双向链表,它与普通双链表的区别在于两个方面:首尾节点互相连接,形成一个循环,同时每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。这种结构使得循环双链表在某些场景下更灵活,可以方便地从两个方向遍历链表。
特点
循环性质
循环双链表的首节点的前驱指针指向尾节点,尾节点的后继指针指向首节点,形成一个环状结构。
双向性质
每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点,这使得在链表中可以方便地从前往后或从后往前遍历。
struct Node {
int data; // 存储数据的成员
struct Node* prev; // 指向前一个节点的指针
struct Node* next; // 指向后一个节点的指针
};
基本操作
初始化
初始化一个循环双链表时,可以将首尾节点互相连接。
head->next = head;
head->prev = head;
插入操作
在头部插入新节点
newNode->next = head->next;
newNode->prev = head;
head->next->prev = newNode;
head->next = newNode;
在尾部插入新节点
newNode->next = head;
newNode->prev = head->prev;
head->prev->next = newNode;
head->prev = newNode;
在中间插入新节点
newNode->next = current->next;
newNode->prev = current;
current->next->prev = newNode;
current->next = newNode;
删除操作
删除节点可以在链表的头部、尾部或者中间位置进行。
在头部删除节点
temp = head->next;
temp->next->prev = head;
head->next = temp->next;
free(temp);
在尾部删除节点
temp = head->prev;
temp->prev->next = head;
head->prev = temp->prev;
free(temp);
在中间删除节点
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
free(temp);
遍历操作
遍历循环双链表可以从头节点开始,一直遍历到头节点。
temp = head->next;
while (temp != head) {
// 处理当前节点
// ...
temp = temp->next;
}
逆向遍历
由于每个节点都有前驱指针,因此也可以逆向遍历链表。
temp = head->prev;
while (temp != head) {
// 处理当前节点
// ...
temp = temp->prev;
}
小结
循环双链表的结构使得在某些场景下具有更大的灵活性,但在实际应用中需要注意维护好链表的循环结构,以防止出现死循环等问题。
完整代码实现
#include<stdlib.h>
#include<stdio.h>
typedef struct DNode{
int data;
struct DNode *prior,*next;
}DNode,*DLinkList;
//初始化双链表
bool InitDLinkList(DLinkList &L){
L=(DNode *)malloc(sizeof(DNode));//分配头节点
if(L==NULL){
return false;//内存不足,分配失败
}
L->next=L;//后件
L->prior=L;//前件
return true;
}
//判断双链表是否为空
bool Empty(DLinkList L){
if(L->next==L){
return true;
}
return false;
}
//在节点p之后插入节点s
bool InsertNextDNode(DNode *p,DNode *s){
//判断节点是否合法
if(p==NULL||s==NULL){
return false;
}
if(p->next!=NULL){
s->next=p->next;
}
s->prior=p;
p->next=s;
return true;
}
//在节点p之后插入节点s
bool DeleteNextDNode(DNode *p){
//判断节点是否合法
if(p==NULL){
return false;
}
DNode *s=p->next;
//判断p是否为最后一个节点
if(s==NULL){
return false;
}
p->next=s->next;
s->next->prior=p;
free(s);
return true;
}
//双链表的删除
void DeleteList(DLinkList &L){
while(L->next!=L){
DeleteNextDNode(L);
free(L);
L->next=L;//头指针指向L
}
}
int main(){
DLinkList a;
}