节点类的定义
template <class T>
class Node{
public:
T data; //存放数据
Node<T> * next; //指向下个节点
Node(const T& item){ //用item元素初始化节点
data=item;
next=NULL;
}
~Node(){};
};
循环链表类的定义
template <class T>
class RoundList{
private:
Node<T> * head; //首节点
Node<T> * cur; //当前节点
int size; //链表元素个数
public:
RoundList(){
head=NULL;
cur=NULL;
size=0;
}
~RoundList(){}
void insert(const T& item);
//插入节点
void pop();
//弹出当前节点
void display();
//打印链表元素
T top();
//获得当前节点的值
void del();
//删除指定节点
int count();
//链表元素个数
bool empty();
//是否为空链表
Node<T> * GetPre(Node<T> * N);
//获得节点N的前驱节点
Node<T> * GetCur();
//获得当前节点
void MovCur(int n);
//把当前节点向后移动n个节点
void SetCur(int n);
//设置当前节点初始位置
};
链表类的实现
通过循环遍历的方式来像数组一样通过位序访问元素
template <class T>
//类似于尾插法,没有头节点
void RoundList<T>::insert(const T& item){
Node<T> * tmp=new Node<T>(item);
tmp->next=head;
if(cur==NULL){
head=tmp;
cur=tmp;
size++;
}
else{
cur->next=tmp;
cur=tmp;
size++;
}
}
template <class T>
bool RoundList<T>::empty(){
return size==0;
}
template <class T>
T RoundList<T>::top(){
return cur->data;
}
template <class T>
void RoundList<T>::display()
{
Node<T> * ptr=head;
for (int i=0;i<size;i++){
cout<<ptr->data<<"->";
ptr=ptr->next;
}
cout<<endl;
}
template <class T>
int RoundList<T>::count(){
return size;
}
//获得n的前驱节点
template <class T>
Node<T> * RoundList<T>::GetPre(Node<T> * N){
Node<T> * ptr=head;
while (ptr->next!=N)
{
ptr=ptr->next;
}
return ptr;
}
template <class T>
Node<T> * RoundList<T>::GetCur(){
return cur;
}
template <class T>
void RoundList<T>::pop(){
Node<T> * pre= GetPre(cur);
pre->next=cur->next;
size--;
}
template <class T>
void RoundList<T>::SetCur(int n){
cur=head;
for (int i = 0; i < n-1; i++)
{
cur=cur->next;
}
}
template <class T>
void RoundList<T>::MovCur(int n){
for (int i = 0; i < n; i++)
{
cur=cur->next;
}
}
测试循环链表类
int main(){
RoundList<int> L;
// L.insert(33);
// L.insert(22);
// L.insert(11);
// L.display();
// cout<<endl;
// cout<<L.top()<<endl;
// RoundList<int> L;
L.insert(1);
L.insert(2);
L.insert(3);
L.insert(4);
L.insert(5);
L.insert(6);
// 测试SetCur和MovCur
// L.SetCur(0);
// cout<<L.GetCur()->data<<endl;
// L.MovCur(4);
// cout<<L.GetCur()->data<<endl;
//测试插入删除
// L.pop();
// L.display();
//测试GetCur 和 GetPre
// Node<int> * p= L.GetCur();
// cout<<p->data<<endl;
// Node<int> * ptr = L.GetPre(p);
// cout<<ptr->data<<endl;
}
用自己的循环链表类解决约瑟夫问题
约瑟夫问题
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。
int main()
{
L.insert(1);
L.insert(2);
L.insert(3);
L.insert(4);
L.insert(5);
L.insert(6);
//初始化六个人
cout<<"人员如下:"<<endl;
L.display();
cout<<"输入初始位置n"<<endl;
int n;
cin>>n;
//这里从第一个人开始数的话要把初始位置n置为最后一个元素
//从第n个人开始数要把初始位置n置为第n-1个元素
if (n==0)
{
L.SetCur(L.count());
}
else
{
L.SetCur(n-1);
}
cout<<"每传递x个位置"<<endl;
int x;
cin>>x;
std::cout << "顺序如下" << std::endl;
while (!L.empty())
{
L.MovCur(x);
cout<<L.top()<<" ";
L.pop();
/* code */
}
}