您的位置:首页 > 编程语言 > C语言/C++

C++不带头结点的单循环链表解决约瑟夫环问题

2014-03-24 14:46 411 查看
重新把殷人昆的C++数据结构(2版)重新走一遍,发现以前的基础太差,这个简单的基础的东西都搞了好久才搞出来啊~~~~~

言归正题:

首先建立要力一个CircList.h头文件代码如下:

//不带头结点的单循环链表

#ifndef CIRCLIST_H
#define CIRCLIST_H

#ifndef CH_H
#define CH_H
#include <stdlib.h>
#include<iostream>
using namespace std;
#endif

template<typename 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<typename T>
class circList
{
public:
circList();
circList(const T& x);
circList(circList<T>& L);
~circList();
int Length()const;
void makeEmpty();
bool IsEmpty(){ return first ->link==first ? true : false; }
/*bool IsFull(){ return last->link == first ? true : false; }*/
CircLinkNode<T> *getHead(){ return first; }
bool Insert(int i, T& x);
bool Remove(int i, T& x);
bool setData(int i, T& x);
bool getData(int i, T& x);
CircLinkNode<T>* Search(T x);
CircLinkNode<T>* Locate(int i);
void output();
void inputFront(T endTag);
void inputRear(T endTag);
private:
CircLinkNode<T> *first, *last;
};
//////////////////////////////////////////////////////////////////////////

template<typename T>
circList<T>::circList()
{
first = last = NULL;
}

template<typename T>
circList<T>::circList(const T& x)
{
first = last = NULL;
}

template<typename T>
circList<T>::circList(circList<T>& L)
{
T value;
CircLinkNode<T>* srcptr, *destptr;
srcptr = L.first;
first = destptr = new CircLinkNode<T>(srcptr->data);
while (srcptr!=L.first)
{
value = srcptr->link->data;
destptr->link = new CircLinkNode<T>(value);
destptr = destptr->link;
srcptr = srcptr->link;

}
last = destptr;
last->link = first;
}

template<typename T>
circList<T>::~circList()
{
makeEmpty();
}

template<typename T>
int circList<T>::Length()const
{
int count=0;
CircLinkNode<T>* p = first;
while (p->link!=first)
{
p=p->link;
count++;
}
return ++count;
}

template<typename T>
void circList<T>::makeEmpty()
{
CircLinkNode<T>* del;
while (first!=NULL)
{
del = first;
first = first->link;
delete del;
}
last = NULL;
}

template<typename T>
bool circList<T>::Insert(int i, T& x)
{
//向后插入
if (i<0)
{
return false;
}
CircLinkNode<T> *current = Locate(i);
if (current==NULL)
{
return false;
}
CircLinkNode<T> *newNode = new CircLinkNode<T>(x);
if (newNode==NULL)
{
cerr << "内存分配失败!" << endl;
}
if (current!=last)
{
newNode->link = current->link;
current->link = newNode;
return true;
}
else
{
newNode->link = first;
last->link = newNode;
last = last->link;

}

}

template<typename T>
bool circList<T>::Remove(int i, T& x)
{
CircLinkNode<T> *current = Locate(i);
if (current==NULL)
{
return false;
}
else if (current == first)
{
first = first->link;
x = current->data;
delete current;

}
else if (current==last)
{
CircLinkNode<T>* temp = Locate(i - 1);
temp->link = first;
last = temp;
last->link = first;
delete current;

}
else
{
CircLinkNode<T>* temp = Locate(i - 1);
temp->link = current->link;
delete current;

}
return true;

}

template<typename T>
bool circList<T>::setData(int i, T& x)
{
if (i<0)
{
return false;
}
CircLinkNode<T> *current = Locate(i);
if (!current)
{
return false;
}
current->data = x;
return true;
}

template<typename T>
bool circList<T>::getData(int i,T& x)
{
if (i < 0)
{
return false;
}
CircLinkNode<T> *current = Locate(i);
if (!current)
{
return false;
}
x = current->data;
return true;
}

template<typename T>
//CircLinkNode* circList<T>::Search(T x)const
CircLinkNode<T>* circList<T>::Search(T x)
{
CircLinkNode<T>*  current=first;
while (current!=NULL&¤t->link!=first)
{
if (current->data==x)
{
break;
}
else
{
current = current->link;
}
}
return current;
}

template<typename T>
CircLinkNode<T>* circList<T>::Locate(int i)
{
if (i < 0)
{
return NULL;
}
if (i == 0)
{
return first;
}
CircLinkNode<T>* current = first;
int k = 1;
while (current->link != first && k < i)
{
current = current->link;
k++;
}
return current;
}

template<typename T>
void circList<T>::inputFront(T endTag)
{
CircLinkNode<T>* newNode;
T val;
makeEmpty();
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode<T>(val);
if (newNode == NULL)
{
cerr << "内存分配错误!" << endl;
exit(1);
}
last = first = newNode;
first->link = last;
last->link = first;
while (val != endTag)
{
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode<T>(val);
newNode->link = first;
first = newNode;
last->link = first;//必须把last的指针域更新下,它是不会同步更新的。
}
else
{
break;
}
}
}

}

template<typename T>
void circList<T>::inputRear(T endTag)
{
CircLinkNode<T>* newNode,*current;
T val;
makeEmpty();
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode<T>(val);
first = last = current= newNode;
first->link = last;
last->link = first;
while (val!=endTag)
{
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode<T>(val);
current->link = newNode;
last=current = newNode;
last->link = first;//必须把last的指针域更新下,它是不会同步更新的。
}
else
{
break;
}
}
}

}

template<typename T>
void circList<T>::output()
{
int i = 0;
CircLinkNode<T>* current = first;
while (current!=NULL&¤t->link!=first)
{
cout << "#"<< i<<":" << current->data << endl;
current = current->link;
i++;
}
cout << "#" << i << ":" << current->data << endl;
}

#endif
之后就是测试自己的写的代码和写出约瑟夫环的结果了:
main.cpp如下:

#include "CircList.h"

template<typename T>
void josephus(circList<T>& Js, int n, int m)
{
CircLinkNode<T>* p = Js.Locate(1), *pre = NULL;
for (int i = 1; i < n ;i++)
{
for (int j = 1; j < m; j++)
{
pre = p;
p = p->link;
}
cout << "出列的第"<<i<<"人:" << p->data << endl;
pre->link = p->link;
delete p;
p = pre->link;
}
cout << "最后的幸运者:" << p->data << endl;
}


main.cpp代码如下:

void main()
{
//circList<int> c1,c2;
///*for (int i = 0; i < 5;i++)
//{
// cl.Insert(i, i);
//}*/
//cout << "前插法:" << endl;
//c1.inputFront(-1);
//c1.output();
///*cout << "insert函数插入一个数:"<<endl;
//int x=c1.Length();
//c1.Insert(3, x);
//c1.output();*/

//cout << "Remove函数删除一个数:" << endl;
//int y;
//c1.Remove(3, y);
//c1.output();

//cout << "后插法:" << endl;
//c2.inputRear(-1);
//c2.output();
//cout << "insert函数插入一个数:"<<endl;
//int x1 = c2.Length();
//c2.Insert(3, x1);
//c2.output();

///*int x = 1;
//cl.Insert(1, x);

//cl.output();*/

circList<int> clist;
int i, n, m;
cout << "建立循环链表:" << endl;
clist.inputRear(-1);
cout << "输入游戏的人数和报数间隔:";
cin >> n >> m;
josephus(clist, n, m);

while (1)
{

}
}


注意:血泪史,如果代码是模板类的话,不要把声明和定义分开放在头文件和源文件中,不然会有好多你意想不到的错误啊!!!!

截图效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: