猴子选大王游戏程序

 游戏描述:

        一堆猴子都有编号,编号是1,2,3 ...m ,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第N个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。

 其实这个问题就是约瑟夫环的应用,主要应用循环链表来解决。以下是它的源程序:

#include<iostream.h>
class node    //建立节点类
{  
   private:
        node *next;//nesxt为节点内的指针
   public:
     int data;//节点内的数据域
        node(void);//节点构造函数
        node(int obj);//带一个参数的节点构造函数
        insertnode(node *p);//插入节点函数声明  *p为指针类型参数
   node *deletenode(void);//删除节点函数声明
   node *nextnode(void) const; //查找下一节点函数声明 返回一个node类型的指针变量
};
//具体函数实现
node::node(void)//节点构造函数实现
{
 next=this;//使节点的指针指向自己
}
node::node(int obj)//带一个参数的节点构造函数实现
{
 next=this;  //同上
 data=obj;
}
node::insertnode(node *p)//插入节点函数实现
{
  p->next=next;
  next=p;
}
node *node::deletenode(void)//删除节点函数实现
{
  node *ptr=next;//*ptr指针指向要删除的节点
  if(ptr==this) //如果ptr指向自己,即循环链表中没有节点可删除,然后返回
      return NULL;
  next=ptr->next;//使前一个节点的指针(即next)指向要删除节点的下一个节点
  return ptr; //返回要删除的节点指针
}
node *node::nextnode(void) const//查找下一节点函数实现
{
  return next;
}
void creatmonkey_list(node *header,int n)//建立循环链表
{
  node *current_ptr=header,*newnode_ptr;//current_ptr为当前指针,newnode_ptr为新建节点的指针
  int i;
  for(i=1;i<=n;i++)
  {
    newnode_ptr=new node(i);//创建一个新节点
 current_ptr->insertnode(newnode_ptr);//将这个节点插入到循环链表中
 current_ptr=newnode_ptr;//向后移动指针
  }
}
void choosemonkey_king(node *list,int n,int m)//选猴王函数的实现
{
   node *pre_ptr=list,*current_ptr=list->nextnode();//pre_ptr指向头节点,current_ptr指向头节点的下一个节点
    node *deletenode_ptr;//定义这个指针指向要删除的节点
 int i,j;
 for(i=0;i<n-1;i++)
 {
      for(j=0;j<m-1;j++)
   {
       pre_ptr=current_ptr;//向后移动pre_ptr指针
    current_ptr=current_ptr->nextnode();//向后移动current_ptr指针
    if(current_ptr==list)//如果current_ptr指向链表头,则current_ptr跳过头节点,因为list只是循环链表的头节点标识
    {
        pre_ptr=list;
        current_ptr=current_ptr->nextnode();
    }
   }
   cout<<"第"<<current_ptr->data<<" 只猴子离开。"<<endl;//显示那只猴子离开了
   deletenode_ptr=current_ptr;//保存要删除的节点指针
   current_ptr=current_ptr->nextnode();//current_ptr指向下一个节点
   pre_ptr->deletenode();//删除节点
   delete deletenode_ptr;//释放deletnode_ptr所占的内存
   if(current_ptr==list)//如果只剩一个节点,则这个节点的数值就是猴子王得号码
   {
        pre_ptr=list;
  current_ptr=current_ptr->nextnode();
   }
 }
      cout<<"猴子王是:"<<current_ptr->data<<endl;//显示猴子王号码
  deletenode_ptr=list->deletenode();//删除最后一个节点
  delete deletenode_ptr;//释放最后一个节点的内存空间
}
int main()
{
  node list;
  int num_n,num_m;
  cout<<endl;
  cout<<endl;
  cout<<"-------------------------------------------------------------------------------"<<endl;
  cout<<"|                        ***猴子选大王游戏***                                 |"<<endl;
  cout<<"-------------------------------------------------------------------------------"<<endl;
  cout<<"请输入猴子数目n:";
  cin>>num_n;
  cout<<"请输入要数的数m:";
  cin>>num_m;
  cout<<"离开顺序为:"<<endl;
  creatmonkey_list(&list,num_n);//创建循环链表
  choosemonkey_king(&list,num_n,num_m);//选猴子王
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值