数据结构(2.7)——循环链表

循环单链表

循环单链表与单链表的主要区别在于它们的结构特点。

  1. 单链表:在单链表中,最后一个节点的指针域通常指向null,表示链表的结束。单链表可以简单地理解为链表的一个“线性”结构,从头节点开始,通过每个节点的指针域顺序访问下一个节点,直至最后一个节点。

  2. 循环单链表:循环单链表则不同,其最后一个节点的指针域不是指向null,而是指向链表的第一个节点,形成一个环。这意味着从循环单链表的任何一个节点出发,都可以遍历整个链表。

循环单链表的这个特性带来了一些不同的操作和用途:

  • 遍历:在循环单链表中,因为没有null指针来判断链表的结束,所以在遍历时需要用其他方式来判断是否回到了起点。通常的方法是设置一个计数器,记录遍历的节点数,或者比较当前节点是否与某个特定节点相同(比如头节点)。

  • 操作:循环单链表在插入和删除操作上与单链表类似,但需要注意的是,由于链表是环形的,这些操作需要特别处理指针,以确保环形结构不被破坏。

  • 应用:循环单链表在实现一些算法,如约瑟夫环问题,或者在需要循环数据结构的场景中非常有用。

总的来说,循环单链表通过其环形结构,提供了一种不同于传统线性链表的数据访问和处理方式。

typedef struct LNode {
	int data;
	struct  LNode* next;
}LNode,*LinkList;

//初始化循环单链表
bool InitList(LinkList& L) {
	L = (LNode*)malloc(sizeof(LNode));
	if (L == NULL) {
		return false;
	}
	else {
		L->next = L;
		return true;
	}
}
//判空循环单链表
bool Empty(LinkList L) {
	if (L->next == L) {
		return true;
	}
	else {
		return false;
	}
}
//判断结点p是否为循环单链表的表尾结点
if (p->next == L) {
	return true;
}
else
{
	return false;
}

循环双链表

循环双链表是双链表的一种变体,它在双链表的基础上增加了循环链的特性。在双链表中,每个节点不仅有一个指向下一个节点的指针(称为next指针),还有一个指向前一个节点的指针(称为prev指针)。循环双链表在此基础上,将最后一个节点的next指针指向第一个节点,同时将第一个节点的prev指针指向最后一个节点,形成一个闭环。

循环双链表的特点如下:

  1. 闭环结构:循环双链表的首尾相连,形成一个环,这意味着没有头尾之分,从任何一个节点开始都可以遍历整个链表。

  2. 双向遍历:由于每个节点都有指向前一个节点的指针,循环双链表可以双向遍历,即可以从前往后遍历,也可以从后往前遍历。

  3. 插入和删除操作:循环双链表的插入和删除操作比单链表稍微复杂一些,因为需要同时修改两个方向的指针。但是,由于有prev指针的存在,这些操作在逻辑上更加直观。

  4. 应用场景:循环双链表在需要频繁进行双向遍历或操作的场景中非常有用,如双向队列、时间戳管理等。

  5. 空链表判断:在循环双链表中,判断链表是否为空通常不是通过头节点的next指针是否为null来实现的,因为即使链表为空,头节点的next和prev指针也可能指向头节点自己。因此,通常需要通过其他方式来判断链表是否为空,例如设置一个额外的标志变量。

循环双链表综合了双链表和循环链表的优势,提供了灵活的双向遍历能力和闭环结构的特点,使其在某些特定的数据结构和算法实现中非常有用。

typedef struct DNode {
	int data;
	struct  DNode*prior,* next;
}DNode, * DLinkList;
//初始化循环双链表
bool InitDList(DLinkList& L) {
	L = (DNode*)malloc(sizeof(DNode));
	if (L == NULL) {
		return false;
	}
	else {
		L->prior = L;
		L->next = L;
		return true;
	}
}
//判空循环双链表
bool Empty(DLinkList L) {
	if (L->next == L) {
		return true;
	}
	else {
		return false;
	}
}
//判断结点p是否为循环双链表的表尾结点
bool isTail(DLinkList L, DNode* p) {
	if (p>next == L) {
		return true;
	}
	else {
		return false;
	}
}
//在p结点之后插入s结点
bool InsertNextDNode(DNode* p, DNode* s) {
	s->next = p->nexy;
	p->next->prior = s;
	s->prior = p;
	p->next = s;
}

总结:

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值