详解:循环双链表

  简要介绍

        循环双链表是一种特殊的双向链表,它与普通双链表的区别在于两个方面:首尾节点互相连接,形成一个循环,同时每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。这种结构使得循环双链表在某些场景下更灵活,可以方便地从两个方向遍历链表。

特点 

     循环性质 

     循环双链表的首节点的前驱指针指向尾节点,尾节点的后继指针指向首节点,形成一个环状结构。 

      双向性质 

        每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点,这使得在链表中可以方便地从前往后或从后往前遍历。 

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;

}

 

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云里雾里!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值