数据结构----C++ 判断一个带表头结点的双向循环链表L是否对称相等的算法

设计算法,判断带头结点的循环双向链表是否对称

算法思路:
⚫ 建立两个工作指针p和q,p从左向右扫描L,q从右向左扫描L,两者同时扫描
⚫ 进入while循环判断,若p与q不相等且p的后继不等于q
⚫ 若对应数据结点的data域相等,则继续循环,否则退出循环
⚫ 判断最后一次的数据结点的data域是否相等且sym==1

核心代码:

int CirLinkList::symmetry(){ 
	int sym=1; 
	CirNode *p=first->next, *q=first->prior; 
	while((p!=q&&q!=p->next) && sym==1){
		if (p->data==q->data){ 	
			p=p->next; 
			q=q->prior; 
		} 
		else sym=0;
	}
	if(sym==1 && p->data!=q->data)
		sym=0;
	return sym;
}

调试代码:

#include <iostream>//引入输入输出流 
#include <stdio.h>
#include <stdlib.h>
using namespace std; //将循环双链表的结点结构定义,循环双链表类定义和各个成员函数定义写到这里

typedef int DataType;
typedef struct CirNode
{
	DataType data;//数据域 
	struct CirNode * next;//前驱指针域 
	struct CirNode * prior; //后继指针域 
}CirNode; 

//循环双链表的实现
class CirLinkList{
	public:
		CirLinkList();//建立只有头结点的空链表
		CirLinkList(DataType a[],int n);//建立n个元素的循环双链表
		bool Empty();//判断线性表是否为空
		int Length(); 
		void PrintList();//遍历操作,按序号依次输出各元素
		void GetNode(int i);//通过数据得到结点
		void PrintCirNode(CirNode *node);//遍历操作 
		void RunPrintCirCirNode();//从任意位置遍历链表 
        void Print_NearBothNode(int i);//从任意位置查询结点的前驱和后继 
        void Insert(int i,DataType x); 
        DataType Delete(int i);
        int symmetry();//判断带头结点的循环双向链表是否对称
	private:
		CirNode *first;//循环双链表的头指针 
};

//判断是否为空 
bool CirLinkList::Empty()
{
	if(first->next == first)
	{
		return true;
	}
	else{
		return false;
	}
} 

//求循环双链表的长度 
int CirLinkList::Length(){
	CirNode *p = first->next;//工作指针初始化
	int count = 0;//累加器初始化
	while(p!=first)
	{
		p=p->next;
		count++;	
	}
	return count;//注意count的初始化和返回值之间的关系 
} 

//建立循环双链表 尾插法 
CirLinkList::CirLinkList(DataType a[],int n)
{
	first = new CirNode();
	CirNode *r=first,*s = nullptr;//尾指针初始化
	for(int i=0;i<n;i++)
	{
		s=new CirNode();
		s->data=a[i]; 
		r->next=s;
		s->prior=r;
		r=s;
	}
	r->next=first;//循环链表建立完毕,将终端结点的指针域指向自身 
	first->prior=r;
}

//遍历操作
void CirLinkList::PrintList()//遍历操作,按序号依次输出各元素
{
	CirNode *p = first->next;//工作指针p初始化
	
	while(p!=first)
	{
		if(p==first){
			p=p->next;
			continue;
		} 
		cout<<p->data<"\t";
		p=p->next;//工作指针p后移,注意不能写作p++ 
	}
}

//从任意结点处遍历整个链表 
void CirLinkList::PrintCirNode(CirNode *node)
{
	CirNode *p = node;
	cout<<p->data<<"\t";
	p=p->next;
	while(p!=node)
	{
		if(p==first){
			p=p->next;
			continue;
		}
		cout<<p->data<<"\t";
		p=p->next;
	}
}

//查找任意位置
void CirLinkList::GetNode(int i)
{
	CirNode *p = first->next; //工作指针p初始化
	int count = 1;//累加器count初始化
	while(count<i)
	{
		p = p->next;//工作指针p后移
		count++; 
	} 
	PrintCirNode(p);
	cout<<endl;
	/*
	CirNode *p = first->next; 
    while(1)
    {
        p = p->next;
        if(p->data == i){
        	PrintCirNode(p);
        	break;
        }
    }*/
}

//从任意位置遍历链表 
void CirLinkList::RunPrintCirCirNode()
{
	int locate;
	cout<<"请输入从第几个开始遍历整个链表:";
	cin>>locate;
	GetNode(locate);
}

//从任意位置查询结点的前驱和后继 
void CirLinkList::Print_NearBothNode(int i)
{
	CirNode *p = first->next; //工作指针p初始化
	int count = 1;//累加器count初始化
	while(count<i)
	{
		p = p->next;//工作指针p后移
		count++; 
	} 
	cout<<"当前位置的前驱:"<<p->prior->data<<"当前位置:"<<p->data<<"当前位置的后继:"<<p->next->data<<endl;
}

//插入操作 
void CirLinkList::Insert(int i,DataType x)
{
	CirNode *p=first,*s=nullptr;
	int count=0;
	while(count<i-1)
	{
		p = p->next; //工作指针后移 
		count++;
	}
	s = new CirNode;s->data=x;//申请结点x,数据域为xx
	//s->next = p->next;p->next=s;//将结点s插入到结点p之后 
	s->prior=p;
	s->next=p->next;
	p->next->prior=s;
	p->next=s;
}

//删除操作 
DataType CirLinkList::Delete(int i)
{
	DataType x;
	CirNode*p = first->next;
	int count=0;
	while(p!=first && count<i-1)//查找第i-1个结点 
	{
		p = p->next;
		count++;	
	} 
	if(!p)//结点p不存在或p的后继结点不存在
		throw "删除位置错误";
	else{
		p->prior->next=p->next;
		p->next->prior=p->prior; 
		delete p;
		return x; 
	} 
}

int CirLinkList::symmetry(){ 
	int sym=1; 
	CirNode *p=first->next, *q=first->prior; 
	while((p!=q&&q!=p->next) && sym==1){
		if (p->data==q->data){ 	
			p=p->next; 
			q=q->prior; 
		} 
		else sym=0;
	}
	if(sym==1 && p->data!=q->data)
		sym=0;
	return sym;
}

int main()
{
	int r[5]={1,2,8,2,5},i,x;
	DataType element_data;
	CirLinkList L{r,5};
	cout<<"当 前 链 表 的 数 据 为 : ";
	L.PrintList();//输出 
	cout<<endl;
	if(L.symmetry())
		cout<<"该 链 表 对 称!";
	else
		cout<<"该 链 表 不 对 称!";
	return 0;
} 

调试代码实验结果图:

我是热爱学习的呵呵哒~如果你觉得文章很棒,对你有帮助的话,可以点赞+收藏+加关注喔~

如果文章有不正确的地方,欢迎交流指正,我将虚心请教~o(>ω<)o

我会定期更新文章,继续为您提供优质文章

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

呵呵哒( ̄▽ ̄)"

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

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

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

打赏作者

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

抵扣说明:

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

余额充值