约瑟夫环问题的亲身实践(和循环链表有关)!

最近一直在复习数据结构的相关内容,首先回顾的就是链表这一非常基础和重要的数据结构,而其中的循环链表问题又非常有趣。比如约瑟夫环问题。笔者在回避参考资料的情况下自己写出了如下代码,仅供诸位参考,如果有考虑不周到的地方,欢迎各位交流指正,共同进步,谢谢!(为了突出重点,略去了其他函数,请见谅!)

//首先定义了节点

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个人出列!

程序运行结果如下图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值