链表实现约瑟夫环问题

2.约瑟夫环(综合性实验)

问题描述

约瑟夫问题的一种描述是,编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,位于他顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列。试设计一个程序求出出列顺序。

基本要求

利用单向循环链表存储结构模拟此过程,按照出列的顺序打印出每个人的编号。

测试数据

m的初值为20,密码分别为3、1、7、2、4、8和4(正确的结果应为6、1、4、7、2、3和5)。

实现提示

程序运行后首先要求用户指定初始报数上限值,然后读取每个人的密码(设n≤30)。

本题可使用模板类LinkList,也可使用STLList容器。

注:当时控制台对齐效果做的不好,哈哈!



【MoshowMenu.h】自制简易菜单v1.02
#include <iostream> using namespace std; //②〇①〇〇③〇④〇③〇⑤④ 10软开B(郑锴) 自制简易菜单! //v1.02<2011.10.09> //●AddMenu传参由string xxx改为char xxx[],防止vs2010上通过而vs2008报错 //●Choise增加输入缓冲区清楚机制,防止输入"\&~"等字符导致程序卡死 // void MainMenu() { system("Color 2E"); system("Title 10软开B(郑锴)"); cout<<"\n\n\n\n\t\t ★★姓名→郑锴★★★学号→xxxxxxxxxxx ★★\n" <<"\t \t ***Warning:Don't Ctrl+C Copy Me!Copy必究*** \n \n"; } void AddMenu(char xxx[]) { cout<<"\t\t\t\t●"<<xxx<<endl; } int Choise() { int choise; cout<<"\n\n\t\t请输入选项:"; cin>>choise; cin.clear(); cin.sync(); system("cls"); return choise; } //应用实例: //void main() //{ // int open=1; // xxxx<int> x; // while(open) // { // MainMenu(); // AddMenu("*.初始化x"); // AddMenu("0.退出程序"); // AddMenu("1.__n____"); // AddMenu("2._______"); // switch(Choise()) // { // case 0: // open=0; // cout<<"程序即将退出!"<<endl; // break; // case 1: // int n; // cout<<"输入n:" // x.xxxx(n); // break; // case 2: // x.xxxx(); // break; // default: // cout<<"输入错误!"<<endl; // break; // } // } // system("pause"); //}
【InitList.h】//自制的链表类
#include<iostream> using namespace std; class Node //链表 { public: int data; Node *next; }; Node *initList(int n) //函数:生成链表存放数据 { Node *list = new Node; Node *p = list; p->data = 1; p->next = 0; for (int i = 2; i <= n; i++) { Node *temp = new Node; temp->data = i; temp->next = 0; p->next = temp; p = temp; } p->next = list; return list; } void Print(Node *list) //函数:打印链表 { if (list) { Node *p = list; cout<<p->data; while (p->next != list) { p = p->next; cout<<"→"<<p->data; } } cout<<endl; }
【moshowmain.cpp】主函数
#include"InitList.h" #include"MoshowMenu.h" void main() //Moshow魔手.郑锴 { int n; int m[20]; //入座 MainMenu(); AddMenu("请输入围坐一圈的人数n:"); cin>>n; Node *mylist = initList(n); //给编号! AddMenu("初始编号是:"); Print(mylist); //初始化密码! AddMenu("请输入初始密码m:"); cin>>m[0]; for (int i = 1; i <= n; i++) { cout<<"请输入第"<<i<<"个人的密码:"; cin>>m[i]; } //逐个按顺序出列! AddMenu("出列顺序是: "); int j = 0; Node *p = mylist; Node *t = new Node; while( p->next != p) { for(int k = 1 ; k < m[j] ; k++ ) { t = p; p = p->next; } cout<<p->data<<"→"; j = p->data; t->next = p->next; delete p; p = t->next; } cout<<p->data<<"#end! \n"; //不要忘记还有最后一个人 system("pause"); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值