王道数据结构课后代码题p40 17.设计一个算法用于判断带头结点的循环双链表是否对称(c语言代码实现)

补充循环双链表的知识:循环双链表是一种链表数据结构,在链表的基础上增加了头尾相连的循环特性,即链表的最后一个节点指向第一个节点,同时每个节点除了储存下一个节点的指针外还储存前一个节点的指针,这样可以实现在链表两端快速插入和删除元素的操作。

与普通双链表相比,循环双链表的特点是最后一个节点的 next 指针指向第一个节点,第一个节点的 prior指针指向最后一个节点,这样就构成了一个环形结构。循环双向链表可以作为一种序列容器,可以支持在任意位置插入和删除节点,并且可以通过指向任意节点的指针在 O(1) 时间内访问该节点前一个和后一个节点。

在循环双链表L中,某结点*p为尾结点时,p->next==L;当循环双链表为空表时,其头结点的prior域和next域都等于L。

循环双链表的判空条件为:L->prior==L;

                                           L->next==L;

本题算法思想:让p从左向右扫描,q从右向左扫描,直到他们指向同一结点或相邻结点为止,若他们值相同,则继续进行下去,否则返回0。若比较全部相等,则返回1。

本题需要注意的是循环的跳出条件(p!=q是处理结点个数为奇数的,q->next!=p是判断结点个数为偶数。

偶数情况:

奇数情况:

本题代码如下

int symmetry(linklist* L)//判断循环双链表是否对称
{
	lnode* p = (*L)->next, * q = (*L)->prior;
	while (p!=q && q->next!= p)/* ***注意这里的跳出条件(p!=q是处理结点个数为奇数的,q->next!=p是判断结点个数为偶数)*/
	{
		if (p->data != q->data)
		{
			return 0;
		}
			p = p->next;
			q = q->prior;
	}
		return 1;
}

完整测试代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{
	int data;
	struct lnode* prior;
	struct lnode* next;
}lnode,*linklist;
int n = 5;
int a[5] = { 1,2,3,2,1 };
void buildlinklist(linklist* L)//建立循环双链表
{
	(*L)->next =*L;//初始化头结点
	(*L)->prior =*L;
	lnode * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		lnode *s = (lnode*)malloc(sizeof(lnode));//创建新结点
		s->data = a[i];
		s->next = r->next;//插入新结点
		s->prior = r;
		r->next->prior= s;
		r->next = s;
		r = s;
	}
}
int symmetry(linklist* L)//判断循环双链表是否对称
{
	lnode* p = (*L)->next, * q = (*L)->prior;
	while (p!=q && q->next!= p)
	{
		if (p->data != q->data)
		{
			return 0;
		}
			p = p->next;
			q = q->prior;
	}
		return 1;
}
void print(linklist* L)//输出链表
{
	lnode* k = (*L)->next;
	while (k!=*L)
	{
		printf("%d ", k->data);
		k = k->next;
	}
}
int main()
{
	linklist L=(lnode*)malloc(sizeof(lnode));//创建头结点
	L->next = L;
	L->prior = L;
	buildlinklist(&L);//构建循环双链表
	printf("原始单链表为:");
	print(&L);
	int ret = symmetry(&L);
	if (ret == 1)
	{
		printf("\n带头结点的循环双链表对称");
	}
	else
	{
		printf("带头结点的循环双链表不对称");
	}
	return 0;
}

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力敲代码的小火龙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值