最近一直在复习数据结构的相关内容,首先回顾的就是链表这一非常基础和重要的数据结构,而其中的循环链表问题又非常有趣。比如约瑟夫环问题。笔者在回避参考资料的情况下自己写出了如下代码,仅供诸位参考,如果有考虑不周到的地方,欢迎各位交流指正,共同进步,谢谢!(为了突出重点,略去了其他函数,请见谅!)
//首先定义了节点
template <class T>
class ChainNode{
public:
T data;
ChainNode<T> *link;
};
//定义链表
template <class T>
class Chain{
public:
ChainNode<T> *first;
public:
Chain() {first=0;}
virtual ~Chain();
bool IsEmpty() const {return first==0;}
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x)const;
Chain& Delete(int k);
Chain& Delete(T x,bool Flag);
Chain& Insert(int k,const T& x);
Chain& Reverse();
Chain& Sort();
Chain& SortedAdd(Chain<T>& One,Chain<T>& Two);
void output(ostream& out) const;
void output(ostream& out,int& index) const;
bool K2Mdelete(int&k, int&m,int& indexsize);//此函数即为约瑟夫环问题的求解函数
};
//约瑟夫函数的详细实现
template <class T>bool Chain<T>::K2Mdelete(int&k, int&m,int& indexsize)
{
int itermax=indexsize;
ChainNode<T>* p=first;
for (int j=1;j<k;j++)
p=p->link; //turn to the node of starting counting
for (int i=0;i<itermax;i++)
{
indexsize--; //reduce the size of the circle chain by 1 in each deleting process
ChainNode<T>* s=p;
ChainNode<T>* pre=p;
for (int q=1;q<m;q++)
{
s=s->link; //(s pointer) and (pre pointer) refer to the position to delete
pre=pre->link; //
if (s==first)
{
first=first->link;//if the node to delete is head, then reset the head as the second node of the original chain
}
}
for (int qq=0;qq<indexsize;qq++) // (pre pointer) refers to the element before the position to delete
pre=pre->link;
s=s->link; // delete the node in the position
pre->link=s;
p=s;
this->output(cout,itermax);//display the circle chain of the original size
this->output(cout,indexsize);// display the node left
}
if (indexsize==0)
{
free(first);first=NULL; //finished when all nodes are deleted
}
return 1; //return true
}
int _tmain(int argc, _TCHAR* argv[])
{
Chain<int> CircleChain;
CircleChain.first=(ChainNode<int>*)malloc(sizeof(ChainNode<int>));
int maxsize=0;
ChainNode<int> *circlepos;
p=CircleChain.first;
cout<<"Input how many people"<<endl;
cin>>maxsize;
cout<<endl<<"People number is : "<<maxsize<<endl<<"Building circle chain..."<<endl;
for (int index=0;index<maxsize;index++)
{
circlepos=(ChainNode<int>*)malloc(sizeof(ChainNode<int>));
circlepos->data=index+1;
p->link=circlepos;
p=circlepos;
}
CircleChain.first=CircleChain.first->link;
p->link=CircleChain.first;
CircleChain.output(cout,maxsize);
int k=2,m=4;
CircleChain.K2Mdelete(k,m,maxsize);
return 0;
}
输入10人,从第2人开始数4个人出列!
程序运行结果如下图所示: