约瑟夫环问题(C与C++混合版)

来源:互联网 发布:软件流程图实例 编辑:程序博客网 时间:2024/05/17 05:04

问题描述:

约瑟夫环问题

设有编号为1,2,…,n的n(n>0)个人围成一个圈,每个人持有一个密码m,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的人出圈,…,如此下去,直到所有人都全部出圈为止.当给定任意n和m时,设计算法求n个人出圈的顺序。

代码:

#include<iostream.h>
#include<stdio.h>
typedef int Elemtype;//定义Elemtype为int型
//结构体定义
typedef struct LNode{
 Elemtype index;//报数人在当前环中的编号
 struct LNode * next;
}LNode;

 

//创建结点
LNode *Create_node(int Lnum)
{
 LNode *Lp; //创建结点指针
 Lp=new LNode;
 Lp->index=Lnum; //*Lp指向index,把num的值传给Lnum
 Lp->next=NULL; //*Lp指向下一个元素结点为空,确定*Lp是头结点指针
 return Lp; //返回头结点指针
}

//创建循环链表
LNode *Create_Linklist(LNode *pHead, int Lsum)
{
 int k;
 LNode *p, *temp;//创建两个指针
 for(k=1;k<=Lsum;k++)//遍历整个链表
 {
  p=Create_node(k);
  //如果链表为空,创建链表第一个结点,其next指针指向自身
  if(pHead==NULL)
  {
   temp=p; //把p的值传给temp
   pHead=p; //把p的值传给pHead
   temp->next=pHead; //让*temp指向的下一个位置为pHead
  }
  //否则,执行插入节点操作
  else
  {
   p->next=temp->next;//空白指针跟着*p后面,一个接一个插入
   temp->next=p;
   temp=p; //把p的值再传给temp
  }
 }
 //测试是否生成循环链表成功!
 
 p=pHead;
 k=1;//初始化k的值
 while(p->next!=pHead)//用循环输出链表中的元素
 {
  cout<<"第"<<k<<"个报数人的编号为:"<<p->index<<endl;
  p=p->next;//指针移向下一个位置
  k++;
 }
 
 cout<<"第"<<k<<"个报数人的编号为:"<<p->index<<endl;
 
 return pHead;//返回头指针
}

//执行出列操作
void Delete_Linklist(LNode *pHead,int Lstart, int Ldel)
{
 int i,count=1;//count为计数器
 LNode *p, *temp;
 p=pHead;
 //找到第M个孩子所在的位置
 for(i=1;i<Lstart;i++)
  p=p->next;
 //只剩1个结点时终止循环
 while(p->next!=p)
 {
  //找到要出列的孩子的位置
  for(i=1;i<Ldel;i++)
  {
   temp=p;
   p=p->next;
  }
  //执行出列操作
  temp->next=p->next;//让*temp指向*p后面的结点
  cout<<"第"<<count<<"个出圈的人的编号为:"<<p->index<<endl;
  delete p;//释放*p
  count++;
  //出列者的下一个孩子作为新的第一个报数者
  p=temp->next;
 }
 cout<<"第"<<count<<"个出圈的人的编号为:"<<p->index<<endl;
 delete p;
 //所有人均出列,头结点释放后赋空值,避免出现悬垂指针
 pHead=NULL;
}
//初始化
void init_Josephus(int num)//参数为参加的人数
{


}

int main()
{
 int num=0;//参加的人数
 int code=0;//定义密码
 int start_index=0;//第一个报数人的编号
 LNode *pHead=NULL, *p;
 cout<<endl;
 cout<<"以下需要输入的均为int型整数,如输入错误,请退出程序重新运行!"<<endl;
 cout<<"请输入参加的人数num:"<<endl;
 cin>>num;
 cout<<"请输入密码code:"<<endl;
 cin>>code;
 cout<<"请输入第一个报数人的编号start_index:"<<endl;
 cin>>start_index;
 init_Josephus(num);
 p=Create_Linklist(pHead,num);//调用创建链表函数
 Delete_Linklist(p,start_index,code);//调用删除链表函数


 
}

 

 

 

 

 

 

 

 

 

 

修改代码2

//
//约瑟夫环问题
//
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
typedef int Elemtype;//定义Elemtype为int型
//结构体定义
typedef struct LNode{
 Elemtype index;//报数人在当前环中的编号
 struct LNode * next;
}LNode;


//创建结点
LNode *Create_Node(int data)
{
 LNode *Lp;
 Lp=new LNode;
 if(!Lp)
 {
  cerr<<"内存分配错误!"<<endl;
  exit(0);
 }
 Lp->index=data;
 Lp->next=NULL;
 return Lp;
}

//创建循环链表
LNode *Create_Linklist(LNode *pHead, int List_Num)
{
 int k;
 LNode *p, *q;//创建两个指针
 for(k=1;k<=List_Num;k++)//遍历整个链表
 {
  p=Create_Node(k);
  //如果链表为空,创建链表第一个结点,其next指针指向自身
  if(pHead==NULL)
  {
   pHead=p; //把p的值传给pHead
   q=p; //把p的值传给q
   q->next=pHead; //让*q指向的下一个位置为pHead
  }
  //否则,执行插入节点操作
  else
  {
   p->next=q->next;//空白指针跟着*p后面,一个接一个插入
   q->next=p;
   q=p; //把p的值再传给q
  }
 }
 //测试循环链表是否生成成功!

 cout<<"############链表初始化...############"<<endl;
 p=pHead;
 k=1;//初始化k的值
 while(p->next!=pHead)//用循环输出链表中的元素
 {
  cout<<"############第"<<k<<"个报数人的编号为:"<<p->index<<"############"<<endl;
  p=p->next;//指针移向下一个位置
  k++;
 }
 
 cout<<"############第"<<k<<"个报数人的编号为:"<<p->index<<"############"<<endl;
 cout<<"############链表初始化完成!############"<<endl;
 cout<<endl;
 
 return pHead;//返回头指针
}

//执行出圈操作
void Delete_Linklist(LNode *pHead,int List_start, int List_Code)
{
 int i,count=1;//count为计数器
 LNode *p, *q;
 p=pHead;
 //第一个报数人所在的位置
 for(i=1;i<List_start;i++)
  p=p->next;
 //只剩1个结点时终止循环
 while(p->next!=p)
 {
  
  //找到要出列的报数人的位置
  for(i=1;i<List_Code;i++)
  {  
   q=p;
   p=p->next;  
  }
  //执行出列操作
  
  cout<<"第"<<count<<"个出圈的人的编号为:"<<p->index<<endl;
  if(List_Code!=1)
  {
   q->next=p->next;//让*q指向*p后面的结点
   delete p;//释放*p
   p=q->next;
  }
  else
  {
   q=p;
   p=p->next;
   delete q;
  }
  count++;
 }

  cout<<"第"<<count<<"个出圈的人的编号为:"<<p->index<<endl;
  delete p;
  pHead=NULL;
}

 

int main()
{
 int num=0;//参加的人数
 int code=0;//定义密码
 int start_index=0;//第一个报数人的编号
 LNode *pHead=NULL, *p;
 cout<<endl;
 cout<<"以下需要输入的均为int型整数,如输入错误,请退出程序重新运行!"<<endl;
 cout<<"请输入参加的人数num: ";
 cin>>num;
 cout<<"请输入密码code:" ;
 cin>>code;
 cout<<"请输入第一个报数人的编号start_index: ";
 cin>>start_index;
 p=Create_Linklist(pHead,num);//调用创建链表函数
 Delete_Linklist(p,start_index,code);//调用删除链表函数
 return 1;
 
}

原创粉丝点击