数据结构--约瑟夫环(含密码,C++实现)
2017-10-21 12:21
597 查看
///*约瑟夫环问题是:编号为1,2······,n的n个人按顺时针方向围坐一圈,每人持有一个密码。
***一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,
***报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下
***一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
***利用链式存储结构模拟此问题,按照出列顺序打印各人的编号
***测试数据: m的初值为20,n=7,七个人的密码依次为3,1,7,2,4,8,4。则首先出列的值为6
*** 依次正确的出列顺序应该为6,1,4,7,2,3,5。
*///
<实现代码>
#include <iostream>
using namespace std;
struct People{
int number; //people的编号
int password; //每人持有一个密码
People *next; //创建链表节点people
};
class Joseph{ //循环单链表的创建
private:
int m_iPeopleNumber; //参与的人数
int m_iDeleteNumber; //要删除的序号
int m_iOverNumber; //报数上限
People *head; //链表的头结点
public:
Joseph(int peopleNumber,int deleteNumber,int overNumber);
~Joseph();
bool game();
};
Joseph::Joseph(int peopleNumber,int deleteNumber,int overNumber){
m_iPeopleNumber = peopleNumber;
m_iDeleteNumber = deleteNumber;
m_iOverNumber = overNumber;
People *temp1,*temp2; //创建空指针
for(int i = 1; i <= m_iPeopleNumber; i++){ //for循环用于初始化环
int inputPassword;
cout<<"please enter NO."<<i<<" people's password:";
cin>>inputPassword;
temp1 = new People;
temp1->number = i;
temp1->password = inputPassword;
if(i == 1){ //如果当前链表为空,头指针指向第一个人
head = temp1;
temp2 = temp1;
}
//否则,temp2永远指向尾结点,新建立的结点都插入到temp2之后
else{
temp2->next = temp1;
temp2 = temp1;
}
}
temp2->next = head; //循环链表的实现
}
Joseph::~Joseph(){
delete head;
head = NULL;
}
bool Joseph::game(){ //游戏开始
if(m_iDeleteNumber >= m_iOverNumber || m_iDeleteNumber <= 0 ){
cout<<"Your number is over!!"<<endl;
return false;
}
People *temp1,*temp2,*temp; //创建空指针
//用count定位到第m_iPeopleNumber个人,循环后,temp1指向这个人,temp2指向这个人的上一个人
temp1 = head;
int count;
int a = m_iDeleteNumber; //赋初值
for(int i = 1; i <= m_iPeopleNumber; i++){ //游戏次数是人数减去一
count = 1;
while(count < a){
temp2 = temp1;
temp1 = temp1->next;
count ++;
}
cout<<"Delete it:"<<temp1->number<<endl; //出局人的编号
temp = temp1;
a = temp->password; //记录密码,用来删除下一个人
temp2->next = temp1->next; //将当前出局人的直接前驱和直接后继连接起来
temp1 = temp->next; //下次从当前人的下一个人开始数
delete temp; //释放内存
}
cout<<endl;
head = NULL; //游戏结束没有人剩余
return true;
}
int main(){
int peopleNumber,deleteNumber,overNumber;
cout<<"please enter overNumber:";
cin>>overNumber;
cout<<"please enter peopleNumber:";
cin>>peopleNumber;
cout<<"please enter deleteNumber:";
cin>>deleteNumber;
Joseph J1(peopleNumber,deleteNumber,overNumber);
J1.game();
return 0;
}
<运行结果>
***一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,
***报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下
***一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
***利用链式存储结构模拟此问题,按照出列顺序打印各人的编号
***测试数据: m的初值为20,n=7,七个人的密码依次为3,1,7,2,4,8,4。则首先出列的值为6
*** 依次正确的出列顺序应该为6,1,4,7,2,3,5。
*///
<实现代码>
#include <iostream>
using namespace std;
struct People{
int number; //people的编号
int password; //每人持有一个密码
People *next; //创建链表节点people
};
class Joseph{ //循环单链表的创建
private:
int m_iPeopleNumber; //参与的人数
int m_iDeleteNumber; //要删除的序号
int m_iOverNumber; //报数上限
People *head; //链表的头结点
public:
Joseph(int peopleNumber,int deleteNumber,int overNumber);
~Joseph();
bool game();
};
Joseph::Joseph(int peopleNumber,int deleteNumber,int overNumber){
m_iPeopleNumber = peopleNumber;
m_iDeleteNumber = deleteNumber;
m_iOverNumber = overNumber;
People *temp1,*temp2; //创建空指针
for(int i = 1; i <= m_iPeopleNumber; i++){ //for循环用于初始化环
int inputPassword;
cout<<"please enter NO."<<i<<" people's password:";
cin>>inputPassword;
temp1 = new People;
temp1->number = i;
temp1->password = inputPassword;
if(i == 1){ //如果当前链表为空,头指针指向第一个人
head = temp1;
temp2 = temp1;
}
//否则,temp2永远指向尾结点,新建立的结点都插入到temp2之后
else{
temp2->next = temp1;
temp2 = temp1;
}
}
temp2->next = head; //循环链表的实现
}
Joseph::~Joseph(){
delete head;
head = NULL;
}
bool Joseph::game(){ //游戏开始
if(m_iDeleteNumber >= m_iOverNumber || m_iDeleteNumber <= 0 ){
cout<<"Your number is over!!"<<endl;
return false;
}
People *temp1,*temp2,*temp; //创建空指针
//用count定位到第m_iPeopleNumber个人,循环后,temp1指向这个人,temp2指向这个人的上一个人
temp1 = head;
int count;
int a = m_iDeleteNumber; //赋初值
for(int i = 1; i <= m_iPeopleNumber; i++){ //游戏次数是人数减去一
count = 1;
while(count < a){
temp2 = temp1;
temp1 = temp1->next;
count ++;
}
cout<<"Delete it:"<<temp1->number<<endl; //出局人的编号
temp = temp1;
a = temp->password; //记录密码,用来删除下一个人
temp2->next = temp1->next; //将当前出局人的直接前驱和直接后继连接起来
temp1 = temp->next; //下次从当前人的下一个人开始数
delete temp; //释放内存
}
cout<<endl;
head = NULL; //游戏结束没有人剩余
return true;
}
int main(){
int peopleNumber,deleteNumber,overNumber;
cout<<"please enter overNumber:";
cin>>overNumber;
cout<<"please enter peopleNumber:";
cin>>peopleNumber;
cout<<"please enter deleteNumber:";
cin>>deleteNumber;
Joseph J1(peopleNumber,deleteNumber,overNumber);
J1.game();
return 0;
}
<运行结果>
相关文章推荐
- 数据结构迷宫问题C++实现
- 约瑟夫环的问题编程C++实现
- c++实现数据结构1.顺序表
- 【c++版数据结构】链队列的实现
- 数据结构(C++版) 栈的链接存储结构及实现
- 【数据结构】二叉树的构建及其遍历(C++实现)
- C++循环链表之约瑟夫环的实现方法
- 数据结构_队列_用链表动态建立释放节点实现队列各种操作_C++实现
- 数据结构与算法之贪心算法 C++实现
- 数据结构学习系列二-链表的C++实现
- 浙大数据结构 Maximum Subsequence Sum (C++实现)
- 数据结构复习:几种排序算法的C++实现和二叉树的相关算法实现
- 数据结构二叉堆C++实现 最小堆
- 数据结构-栈 C和C++的实现
- 数据结构-二叉搜索树(Binary Search Tree)的C++实现模板
- 【算法和数据结构】线性表(四)用两个栈来实现队列(C++实现)
- C++的标准模板库STL中实现的数据结构之链表std::list的分析与使用
- 数据结构c++实现----双端队列
- 【数据结构】拾遗(一):图的邻接矩阵创建以及其深广度遍历C++实现
- 数据结构C++实现基本的堆