设计算法,判断带头结点的循环双向链表是否对称
算法思路:
⚫ 建立两个工作指针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
我会定期更新文章,继续为您提供优质文章