#include<iostream>
using namespace std;
template <class T>
struct CircLinkNode
{//链表节点定义
T data;
CircLinkNode<T>*link;
CircLinkNode(CircLinkNode<T>*next=NULL):link(next){
}//初始化指针成员的构造函数
CircLinkNode(T d,CircLinkNode<T>*next=NULL):data(d),link(next){
}//初始化指针成员和数据的构造函数
};
template <class T>
class CircList
{
public:
CircList(const T&x)//构造函数
{
first=new CircLinkNode<T>(x);
if(first==NULL)
{
cerr<<"储存分配失败"<<endl;
return ; //这要是没有会不会有影响
}
first->link=first;
}
CircList(CircList<T>&L) ;//复制构造函数
void makeEmpty();
~CircList() //析构函数
{
makeEmpty();
delete first;
}
int Length() ;//计算循环链表长度
bool IsEmpty()
{
return first==first->link;//头结点的下一结点是否为空
}
CircLinkNode<T>*getHead()const
{
return first;
}
void setHead(CircLinkNode<T>*p)
{
first=p;
}
CircLinkNode<T>*Search(T x) ;//搜索含x的元素
CircLinkNode<T>*Locate(int i) ;//搜索第i个元素的地址
T*getData(int i) ;//取出第i个元素的值
void setData(int i,T&x) ;//用第x修改第i个元素的值
bool Insert(int i,T&x) ;//在第i个元素后插入x
bool Remove(int i,T&x) ;//删除第i个元素,返回该元素的值
void output();
private:
CircLinkNode<T>*first;
} ;
template <class T>
void CircList<T>::makeEmpty()
{
CircLinkNode<T>*temp,*p=first->link;;
while(p!=first)
{
temp=p->link;
delete p;
p=temp;
}
first->link=first;
}
//置空函数思路
//建立工作指针
//创建循环结束条件
//工作指针从头结点开始出发,摘结点,最后删除摘得的结点
template <class T>
CircList<T>::CircList(CircList<T>&L)
{
T value;
CircList<T>*srcptr=L.getHead;//附加头地址
CircList<T>*desptr=first=new CircList<T>;
while(srcptr->link!=first) //判断条件发生变化
{
value=srcptr->link->data;
desptr->link=new CircList<T> (value);
desptr=desptr->link;
srcptr=srcptr->link;
}
};
//复制构造函数思路
//将链表赋值给另一个链表
template <class T>
int CircList<T>::Length()
{
CircLinkNode<T>*p=first->link;//从刚开始
int count=0;
while(p!=first)
{
p=p->link;
count++;
}
return count;
};
//先从头开始
//初始化计数变量
//循环链表,终止条件为当前位置不是头节点)
//遍历完成后返回计数值
template <class T>
CircLinkNode<T>*CircList<T>::Search(T x)
{
CircLinkNode <T>*current=first->link;//从头开始找
while(current->link!=first)
{
if(current->data==x)
{
cout<<"该元素存在于单链表中"<<endl;
break;
}
else
{
current=current->link;//后移
}
}
cout<<"不存在该元素!"<<endl;
return NULL;
};
template <class T>
CircLinkNode<T>*CircList<T>::Locate(int i)
{
if(i<0)
{
return NULL;
}
CircLinkNode<T>*current=first;
int k=0;
while(current!=NULL&&k<i)//超出判断
{
k++;
current=current->link;//指针移动
}
return current;
};
template<class T>
T*CircList<T>::getData(int i)
{
if(i<0)
{
return NULL;
}
CircLinkNode<T>*current=Locate(i);//定位
if(current==NULL)
return NULL;
else
{
cout<<"该位置的值为"<<current->data<<endl;
return ¤t->data;//取出数值
}
};
template<class T>//对第I个1位置进行赋值的函数
void CircList<T>::setData(int i,T&x)
{
if(i>Length())
{
i=i%Length();
}
if(i<=0)
{
cout<<"错误!"<<endl; //return NULL
}
CircLinkNode<T>*current=Locate(i) ;
if(current==NULL)
cout<<"错误!"<<endl; //return NULL
else
current->data=x;
} ;
template<class T>
bool CircList<T>::Insert(int i,T&x) //将x元素插入到第i位之后
{
CircLinkNode<T>*current=Locate(i); //怎么这里不严谨了不检查了,我就很奇怪
//设置查找指针
CircLinkNode<T>*newNode=new CircLinkNode<T>(x) ;
if(newNode==NULL)
{
cerr<<"储存分配错误!" <<endl;
exit(1);//退出程序
}
newNode->link=current->link;
current->link=newNode;
return true;// x先下后上
};
template <class T>
bool CircList<T>::Remove(int i,T&x)
{
CircLinkNode<T>*current=Locate(i-1) ;//删除i位置,首先要找到它前面的位置
if(current==NULL||current->link==NULL)
{
return false; }
CircLinkNode<T>*del=current->link;//摘下删除节点
current->link=del->link;
x=del->data;
cout<<"删除的元素为"<<x<<endl;
delete del;
return true;
};
template<class T>
void CircList<T>::output()
{
CircLinkNode<T>*current=first->link;
while(current!=first)
{
cout<<current->data<<" ";
current=current->link;//移动
}
};
int main()
{
cout<<"-----------------创建链表-----------------"<<endl;
CircList<int>cli(0);
int n;
cout<<"请输入循环链表的长度";
cin>>n;
int a[1001];//可修改
cout<<"请输入链表的各个元素";
for(int i=1;i<=n;i++)
{
cin>>a[i];
cli.Insert(i,a[i]);
}
cout<<"------------创建链表成功!-----------"<<endl;
cli.output();
cout<<"循环链表长度"<<cli.Length()<<endl;
cout<<"插入i位置之后以及元素" <<endl;
int i1;
int x1;
cin>>i1>>x1;
if(i1>cli.Length());
i1=i1%cli.Length();
cli.Insert(i1,x1);
cout<<"插入元素后的链表为" <<endl;
cli.output();
cout<<"链表长度为" <<cli.Length()<<endl;
cout<<"请输入需要删除的位置"<<endl;
int i2;
cin>>i2;
if(i2>cli.Length());
i2=i2%cli.Length();
int x2;
cli.Remove(i2,x2);
cout<<"删除后的链表为" <<endl;
cli.output();
cout<<"请输入要取的元素位置"<<endl;
int i3;
cin>>i3;
cli.getData(i3);
cout<<"请输入要修改的位置及要修改后的元素" <<endl;
int i4,x4;
cin>>i4>>x4;
cli.setData(i4,x4);
cout<<"修改后的链表为"<<endl;
cli.output();
return 0;
}