约瑟夫环(内含源代码)

合集下载

c语言经典例题古老问题的解决

c语言经典例题古老问题的解决

c语言经典例题古老问题的解决以下是一个经典的C语言例题,它是关于解决一个古老的问题:约瑟夫环问题。

约瑟夫环问题是一个著名的数学和计算机科学问题,其描述如下:有n个人围成一圈,从第k个人开始报数,数到m的人出圈,然后从下一个人开始重新报数,数到m的人再出圈,直到剩下最后一个人。

求最后留下的人在原序列中的编号。

以下是一个使用C语言解决这个问题的示例代码:```cinclude <>include <>int main() {int n, k, m;printf("请输入人数n:");scanf("%d", &n);printf("请输入开始报数的位置k:");scanf("%d", &k);printf("请输入数到m的人出圈的数m:");scanf("%d", &m);int a = (int )malloc(n sizeof(int));for (int i = 0; i < n; i++) {a[i] = i + 1;}int index = k - 1; // 初始位置为第k个人while (n > 1) {for (int i = 0; i < n; i++) {index = (index + m - 1) % n; // 计算下一个要出圈的人的位置printf("出圈的人是:%d\n", a[index]);free(a[index]); // 释放该位置的内存n--; // 人数减1}if (index >= k) { // 如果最后一个出圈的人的位置大于等于k,则交换位置,保证下次从第k个人开始报数int temp = a[index];a[index] = a[0];a[0] = temp;}index = (index + 1) % n; // 重新开始报数}printf("最后留下的人是:%d\n", a[0]); // 最后留下的人即为所求结果 free(a); // 释放整个数组的内存return 0;}```该程序首先要求用户输入人数n、开始报数的位置k和数到m的人出圈的数m,然后创建一个长度为n的数组a,将数组中的元素初始化为1到n 的整数。

约瑟夫环问题(Josephus)源代码讲解

约瑟夫环问题(Josephus)源代码讲解

原题:用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。

写出C程序。

(约瑟夫环问题 Josephus)提示:由于当某个人退出圆圈后,报数的工作要从下一个人开始继续,剩下的人仍然是围成一个圆圈的,可以使用循环表,由于退出圆圈的工作对应着表中结点的删除操作,对于这种删除操作频繁的情况,选用效率较高的链表结构,为了程序指针每一次都指向一个具体的代表一个人的结点而不需要判断,链表不带头结点。

所以,对于所有人围成的圆圈所对应的数据结构采用一个不带头结点的循环链表来描述。

设头指针为p,并根据具体情况移动。

为了记录退出的人的先后顺序,采用一个顺序表进行存储。

程序结束后再输出依次退出的人的编号顺序。

由于只记录各个结点的number值就可以,所以定义一个整型一维数组。

如:int quit[n];n为一个根据实际问题定义的一个足够大的整数。

代码:/******************************************************************** created: 2006/06/14 filename: C:\Documents and Settings\Administrator\桌面\tmpp\josephus.c file path: C:\Documents and Settings\Administrator\桌面\tmpp file base: josephus file ext: c author: A.TNG version: 0.0.1 purpose: 实现 Josephus 环问题用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。

写出C程序。

(约瑟夫环问题 Josephus)*********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> /* 结构体和函数声明 */ typedef struct _node_t { int n_num; struct _node_t *next; } node_t; node_t *node_t_create(int n); node_t *node_t_get(node_t **pn, int m); /* 功能函数实现 */ /* * name: node_t_create * params: * n [in] 输入要构造的链表的个数 * return: * 返回构造成功的环形单向链表指针 * notes: * 构造节点数量为 n 的环形单向链表* * author: A.TNG 2006/06/14 17:56 */ node_t * node_t_create(int n) { node_t *p_ret = NULL; if (0 != n) { int n_idx = 1; node_t *p_node = NULL; /* 构造 n 个 node_t */p_node = (node_t *) malloc(n * sizeof(node_t)); if (NULL == p_node) return NULL; else memset(p_node, 0, n * sizeof(node_t)); /* 内存空间申请成功 */ p_ret = p_node; for (; n_idx < n; n_idx++) { p_node->n_num = n_idx; p_node->next = p_node + 1;p_node = p_node->next; } p_node->n_num = n;p_node->next = p_ret; } return p_ret; } /* * name: main * params: * none * return: * int * notes: * main function * * author: A.TNG 2006/06/14 18:11 */ int main() { int n, m; node_t *p_list, *p_iter; n = 20; m = 6; /* 构造环形单向链表 */ p_list =node_t_create(n); /* Josephus 循环取数 */ p_iter = p_list; m %= n; while (p_iter !=p_iter->next) { int i = 1; /* 取到第 m-1 个节点 */ for (; i < m - 1; i++) { p_iter =p_iter->next; } /* 输出第 m 个节点的值 */ printf("%d\n", p_iter->next->n_num); /* 从链表中删除第 m 个节点 */ p_iter->next = p_iter->next->next; p_iter = p_iter->next; } printf("%d\n", p_iter->n_num); /* 释放申请的空间 */ free(p_list); system("PAUSE"); }。

约瑟夫环代码

约瑟夫环代码

#include <stdio.h>#include <malloc.h>分配内存的头文件#include <string.h>字符串typedef struct node{int number;char name[8];int pwd;struct node * next;}ListNode,*LinkList;void show(){printf("\n----------------约瑟夫环-----------------------\n");printf(" 约瑟夫环介绍(C) \n");printf(" 约瑟夫环测试(D) \n");printf(" 退出(Q) \n");printf("----------------------------------------------\n");printf("请选择:");}void content(){printf(" 编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)一开始任选一个正整数作为报数的上限值m,从某一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,输出出列顺序。

");}void data()建立一个节点的信息{int i,j,k,m,n;//n为总人数,m为初值,k为密码,j为每个人序号,i为报数序号char a[8];//姓名LinkList p=(ListNode*)malloc(sizeof(ListNode));一个节点printf("总人数为:");scanf("%d",&n);printf("%d\n",n);if(n<=0){printf("人数输入错误,请重新输入!\n");scanf("%d",&n);}ListNode *q;q=p;printf("请输入姓名和密码!\n");for(j=1;j<=n;j++){scanf("%s",a); //姓名scanf("%d",&k); //密码if(k<=0){printf("密码值要大于0,请重新输入!");scanf("%d",&k);}p->number=j;strcpy(p->name,a);p->pwd=k;printf("第 %d个人姓名为:",j);printf("%s",p->name);printf(" 第 %d个人密码为:",j);printf("%d\n",p->pwd);if(j!=n){p->next=(ListNode*)malloc(sizeof(ListNode)); p=p->next;}p->next=q;}printf("初值为: ");scanf("%d",&m);printf("%d\n",m);if(m<=0){printf("初值输入错误,请重新输入!\n");scanf("%d",&m);}m--;printf("出列序号是:\n");while(p->next!=p){i=0;while(i!=m){p=p->next;i++;}q=p->next;p->next=q->next;printf("序号:%d",q->number);printf(" 姓名:%s\n",q->name); m=q->pwd;m--;free(q);}printf("序号:%d",p->number);printf(" 姓名:%s\n",p->name);free(p);Return 0;}void main(){char ch;while(1){show();scanf(" %c",&ch);printf("%c\n",ch);switch(ch){case 'C':content();break;case 'D':data();break;case 'Q'://exit(0);break;default:printf("选择错误!\n\n"); break;}}}。

约瑟夫环-数据结构

约瑟夫环-数据结构

数据结构期末试验报告学院:专业:学号:班级:姓名:2010.12.12 Joseph约瑟夫环上机实验报告实验名称:joseph约瑟夫环题目要求的约瑟夫环操作:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

设计一个程序来求出出列顺序。

实验要求:1~)利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。

2~)建立输入处理输入数据,输入m的初值,n ,输入每个人的密码,建立单循环链表。

3~)建立一个输出函数,将正确的输出序列4~)测试数据:m的初值为20,n=7 ,7个人的密码依次为3,1,7,2,4,7,4,首先m=6,则正确的输出是什么?实验过程:1.基本算法以及分析:本程序主要是以建立单循环链表的形式,建立起一个约瑟夫环,然后根据之前创立的结点,输入结点里的一些数据,如下typedef struct Node{int Index; 在当前环中所处的位置,即编号int Password; 在当前环中的所带的密码struct Node *next;}JosephuNode;程序有主函数开始,首先,提示输入创建约瑟夫环环数以及每个环上所带的密码。

然后,开始调用JosephuNode *Creat_Node函数,利用单循环链表建立起约瑟夫环,tail->next = head;就是将最后一个结点的后继指向头结点,函数结尾return head; 将约瑟夫环的头指针返回,并将它赋值head,然后主函数继续调用Josephu函数,通过讲head和Password 引入函数,以建立两个嵌套循环输出并实现如下功能:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

约瑟夫环问题源代码(C语言)

约瑟夫环问题源代码(C语言)

约瑟夫环问题如下:已知n个人(n>=1)围桌一园桌周围,从1开始顺序编号。

从序号为1的人开始报数,顺时针数到m的那个人出列。

他的下一个人又从1开始报数,数到m的那个人又出列。

依此规则重复下去,直到所有人全部出列。

求解最后一个出列的人的编号。

本次实验是以顺序表求解约瑟夫环问题,程序流程图及程序运行结果如下:输入人数、所报数、第一个报数人编号存储并建立一个约瑟夫环通过循环结构依次查找每次出列的人的编号并输出输出最后一个出列的人的编号程序代码如下:#include<iostream>#include<process.h>#include<stdlib.h>using namespace std;struct Node //循环节点的定义{int number; //编号Node *next;};Node *CreateList(Node *L,int &n,int &m); //建立约瑟夫环函数void Joseph(Node *L,int n,int m); //输出每次出列号数函数Node *DeleteList(Node **L,int i,Node *q); //寻找每次出列人的号数int LengthList(Node *L); //计算环上所有人数函数void main() //主函数{system("color 75"); //设置颜色以美观Node *L;L=NULL; //初始化尾指针int n, m;cout<<"请输入人数N:";cin>>n; //环的长度if(n<1){cout<<"请输入正整数!";} //人数异常处理else{cout<<"请输入所报数M:";cin>>m;if(m<1){cout<<"请输入正整数!";} //号数异常处理else{L=CreateList(L,n,m); //重新给尾指针赋值Joseph(L,n,m);}}system("pause");}Node *CreateList(Node *L,int &n,int &m) //建立一个约瑟夫环(尾插法){Node *q;for(int i=1;i<=n;i++){Node *p;p=new Node;p->number=i;p->next=NULL;if(i==1) L=q=p; //工作指针的初始化 else{q->next=p;q=q->next;}}q->next=L;if(L!=NULL){return(L);} //返回尾指针else cout<<"尾指针异常!"<<endl; //尾指针异常处理}void Joseph(Node *L,int n,int m) //输出每次出列的人{int k;cout<<"请输入第一个报数人:";cin>>k;if(k<1||k>n){cout<<"请输入1-"<<n<<"之间的数"<<endl;}else{cout<<"\n出列顺序:\n";for(int i=1;i<n;i++){Node *q = new Node;if(i==1) q=DeleteList(&L,k+m-1,q); //第一个出列人的号数else q=DeleteList(&L,m,q);cout<<"号数:"<<q->number<<endl;delete q; //释放出列人的存储空间}cout<<"最后一个出列号数是:"<<L->number<<endl; //输出最后出列人的号数}}Node *DeleteList(Node **L,int i,Node *q) //寻找每次出列的人{if(i==1) i+=LengthList(*L); //顺序依次出列情况的处理方式Node *p;p=*L;int j=0;while(j<i-2) {p=p->next;j++;}q = p->next;p->next=p->next->next;*L = p->next;return(q);}int LengthList(Node *L) //计算环上的人数{if(L){cout<<"尾指针错误!"<<endl;} //异常处理else{int i=1;Node *p=L->next;while(p!=L){i++;p=p->next;}return(i);}}实验体会:通过对本问题的分析,我进一步熟悉了对各种逻辑表达式的判断和指针的使用。

约瑟夫环 源代码

约瑟夫环  源代码

#include"stdio.h"#include"stdlib.h"#include"malloc.h"#include"conio.h"#define ERROR 1#define OK 0typedef int ElemType;typedef int Status;typedef struct LNode{ElemType code;ElemType number;struct LNode *next;}LNode,*LinkList;Status CreateLink_L(LinkList &L,int n){struct LNode *p,*q;int i;if(n<=0)return ERROR;printf("请输入个人的密码:");L = (LinkList)malloc(sizeof(LNode));L -> next = NULL;L -> number=1;scanf("%d",&L->code);p=L;q=L;for(i = 2;i <= n;++i){L = (LinkList)malloc(sizeof (LNode));L -> next = NULL;L -> number = i;scanf("%d",&L->code);q-> next=L;q = L;}L->next=p;//首尾链接,L指向最后一个人return OK;Status ListDelete_L(LinkList &L,int n,int k,ElemType &code,ElemType &number) {int i;LinkList p=NULL;if(L->next==L) //{p=L;L=NULL;}else{k=(k-1+n)%n;//该移动的次数for(i=1;i<=k;i++) L=L->next;//点到出列的前一个人p=L->next;//该出列的人L->next=p->next;}code=p->code;number=p->number;free(p);return OK;}Status Josephus_L(LinkList &L,int n){ElemType code=0;ElemType number=0;int m;if(L==NULL)return ERROR;printf("请输入m的初值:");scanf("%d",&m);printf("先后出列的人是:");while(L!=NULL){ListDelete_L(L,n--,m,code,number);m=code;printf("%d ",number);}printf("\n");return OK;}int main()LinkList L=NULL;int n;int m;printf("请输入人数:");while(!scanf("%d",&n)||n<=0){printf("请输入一个正整数:");fflush(stdin);}if(!CreateLink_L(L,n)) // 判断链表是否创建成功Josephus_L(L,n);elseprintf("创建链表失败");printf("按任意键结束程序");getch();return 0;}。

(完整word版)C语言约瑟夫环问题

(完整word版)C语言约瑟夫环问题

实验一:约瑟夫环问题一.实验目的:要求设计一个程序模拟约瑟夫环问题过程,求出出列编号序列。

二.实验内容:约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一个正整数密码.开始时任选一个正整数做为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m是停止报数,报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数。

如此下去,直到所有人全部出列为止。

令n最大值取30。

要求设计一个程序模拟此过程,求出出列编号序列。

三.实验过程:用一个不带头结点的循环链表来处理Josephu 问题:先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,计到m时,对应结点从链表中删除,把被删除结点的密码作为新的m值,然后再从被删除结点的下一个结点又从1开始计数,直到最后一个结点从链表中删除算法结束。

#include〈stdio.h>#include<stdlib。

h〉#define MAX_NODE_NUM 30#define TRUE 1#define FALSE 0typedef struct NodeType{ int number;int password;struct NodeType *next;}NodeType;/*创建单向循环链表*/static void CreaList(NodeType **,const int);/*运行”约瑟夫环"问题*/static void StatGame(NodeType **, int);/* 打印循环链表*/static void PrntList(const NodeType *);/*得到一个结点*/static NodeType *GetNode(const int, const int);/*测试链表是否为空,空为TRUE,非空为FALSE */ static unsigned EmptyList(const NodeType *);int main(void){ int n,m;NodeType *pHead=NULL;while(1){printf("输入总的人数n(〈=%d):”,MAX_NODE_NUM);scanf("%d",&n);printf(”初始循环的密码为:”);scanf(”%d”,&m);if(n>MAX_NODE_NUM){printf("数字太大,请重新输入!\n");continue;}elsebreak;}CreaList(&pHead,n);printf("\n打印出原始每个结点的序列号和密码\n"); PrntList(pHead);printf(”\n最终每个结点退出的序列号和密码\n");StatGame(&pHead,m);return 0;}static void CreaList(NodeType **ppHead, const int n) {int i,iCipher;NodeType *pNew, *pCur;for(i=1;i〈=n;i++){printf("第%d个人的密码为:",i);scanf(”%d",&iCipher);pNew=GetNode(i,iCipher);if(*ppHead==NULL){*ppHead=pCur=pNew;pCur->next=*ppHead;}else{pNew-〉next=pCur—〉next;pCur-〉next=pNew;pCur=pNew;}}printf(”已完成结点初始化!\n”);}static void StatGame(NodeType **ppHead, int iCipher){int iCounter,iFlag=1,i=1;NodeType *pPrv, *pCur,*pDel;pPrv=pCur=*ppHead;while(pPrv—〉next!=*ppHead)pPrv=pPrv->next;while(iFlag){for(iCounter=1;iCounter〈iCipher;iCounter++){pPrv=pCur;pCur=pCur->next;}if(pPrv==pCur)iFlag=0;pDel=pCur;pPrv-〉next=pCur-〉next;pCur=pCur-〉next;iCipher=pDel—〉password;printf("第%d个退出的是序列号为%d的人,其密码为:%d\n",i, pDel—>number,pDel-〉password);free(pDel);++i;}*ppHead=NULL;}static void PrntList(const NodeType *pHead){const NodeType *pCur=pHead;if (EmptyList(pHead))return;do{printf("第%d 个人,密码:%d\n”,pCur->number,pCur->password);pCur=pCur—〉next;} while (pCur!=pHead);}static NodeType *GetNode(const int iId,const int iCipher){NodeType *pNew;pNew=(NodeType *)malloc(sizeof(NodeType));if(!pNew){printf("错误,内存不足!\n”);exit(—1);}pNew—>number=iId;pNew-〉password=iCipher;pNew—>next=NULL;return pNew;}static unsigned EmptyList(const NodeType *pHead){if(!pHead){printf(”列表为空!\n”);return TRUE;}return FALSE;}。

约瑟夫环问题(python3.x)

约瑟夫环问题(python3.x)

约瑟夫环问题(python3.x)数据结构⽼师给我们留了约瑟夫环问题,结合我刚刚学完python想巧妙利⽤python中的列表切⽚来实现⼀个环形列表。

下⾯不多BB直接上代码。

1 n=int(input("输⼊n:")) #⾸先输⼊两个数m,n2 m=int(input("输⼊m:"))3 ls=[] #定义⼀个空列表4for x in range(1,n+1): #将为输⼊的 n 从1开始加到空列表中5 ls.append(x)6 length=n #先给length 赋值 n7if m!=1:8while length>m: #当满⾜while循环时9for i in range(1,length+1):10if i == m:11 a=ls[i:] #通过两次列表切⽚巧妙地将复合条件的数字剔除12 b=ls[:i-1] #注意是从 1开始的不是 0开始的所以列表索引减⼀13for j in b: #将切⽚得到的两个列表合并将靠前的切⽚贴到后⾯巧妙形成⼀个循环14 a.append(j)15 length=len(a) #重新给length赋值是新的到的列表a16 ls=a #将列表a 赋值给 ls17break18continue19if length == m: #如果最后的length = m 则删除索引为m-1的列表元素20del(ls[m-1])21 length=len(ls)22#下⾯对于m<n的情况23while (length < m):24if length != 1:25 cnt = m%length #巧妙求余运算使剩下编号形成⼀个环26if cnt>1: #对余数三种情况讨论27 a=ls[cnt:]28 b=ls[:cnt-1]29for j in b:30 a.append(j)31 length = len(a)32 ls=a33elif cnt==1:34del(ls[cnt-1])35 length=len(ls)36continue37elif cnt==0:38del(ls[length-1])39 length=len(ls)40continue41else:42break43print(ls[0])44else:45print(n)好吧后⾯注释同上。

10行Python代码解决约瑟夫环(模拟)

10行Python代码解决约瑟夫环(模拟)

10行Python代码解决约瑟夫环(模拟)写这篇文章是因为看到别人博客里用了很长一个篇幅(超过50行)去解决一个约瑟夫环问题,而且还是用以简洁著称的python,另外,如果你用X度搜索python 约瑟夫,看到得前几条都是错的,真是好悲剧。

总的来说,就是误人子弟。

虽然,用模拟去解决这个约瑟夫环问题效率是很低的,但是,这更容易理解。

先上代码。

1.def josephus(n,k):2.link=range(1,n+1)3.ind=04.for loop_i in range(n-1):5.ind = (ind+k)% len(link)6.ind-=17.print 'Kill:',link[ind]8.del link[ind]9.if ind==-1: # the last element of link10.ind=011.print 'survice :',link[0]12.13.14.if __name__ == '__main__':15.16.josephus(100000,300)17.print '-'*3018.josephus(10,5)19.print '-'*3020.josephus(10,1)21.22.可以看到,整个函数也就是只有十行。

思路非常简单,按模来找到要删除得位置,但是,主要到下标从0开始和数字从1开始是有一些不一样得,另外,py的del后,下标会增1,所以要减回去。

正确看是del link[ind-1]ind-=1但是,因为两者都需要后退1,所以直接ind-=1就OK了。

另外要主要得是,来到环尾部,即py的-1(这点就是最好的地方,py得tuple 和list 支持负下标),删除后,开始就要变成0如果你认为我写错了,一定要评论给我指出,不想误人子弟。

约瑟夫环c 源代码讲解

约瑟夫环c  源代码讲解

#include <iostream> using namespace std; #define max 100 class node // 结点定义{public: int data; int secret_num; node *next; }; class Linklist //线性表定义 {public: Linklist(); ~Linklist(); node *head; node *pcurrent; void insert(int x,inta,Linklist&team); void Deletecurrent(Linklist&team); }; Linklist::~Linklist() {cout<<"欢迎再玩"; } Linklist::Linklist() //构造函数定义 {head=NULL; } voidLinklist::insert(int x,int a,Linklist&team) //线性表输入函数定义 {if (head==NULL) { node *newnode=new node; newnode->data=x; newnode->secret_num=a;pcurrent=head=newnode; } else {node *newnode=new node; newnode->data=x; newnode->secret_num=a; pcurrent->next=newnode; pcurrent=newnode; pcurrent->next=head; } } void Linklist::Deletecurrent(Linklist&team) //线性表删除函数定义,删除当前(pcurrent)结点 { node *p=pcurrent; while(p->next!=pcurrent)p=p->next; p->next=pcurrent->next; delete pcurrent; pcurrent=p->next; } int main() {intn,m,secret[max]; cout<<"请输入玩游戏人数:"; cin>>n; cout<<"请输入第一个人开始报数的数字:"; cin>>m; cout<<"请输入每个人的密码,并用空格隔开,输入完成后按下回车键"; int i,j; for(i=0;i<n;i++) cin>>secret[i]; Linklist team;for(i=0;i<n;i++) team.insert(i,secret[i],team); cout<<"出列的顺序是:"<<endl; if(n==1) //玩游戏人数只有一人 { cout<<team.head->data+1<<endl; return 0; } node*h=team.head; for(i=0;i<(m-1);i++) { h=h->next; team.pcurrent=h; } if(m==1) //当m=1时 {cout<<team.head->data+1<<endl; m=team.head->secret_num;team.pcurrent=team.head; team.Deletecurrent(team); } else { cout<<team.pcurrent->data+1<<endl; m=team.pcurrent->secret_num; team.Deletecurrent(team); }for(i=0;i<n-1;i++) //第一个人出列后,取他的密码继续进行 {if(m==1){cout<<team.pcurrent->data+1<<endl; m=team.pcurrent->secret_num;team.Deletecurrent(team); } else {int t; for(t=0;t<(m-1);t++)team.pcurrent=team.pcurrent->next; cout<<team.pcurrent->data+1<<endl;m=team.pcurrent->secret_num; team.Deletecurrent(team); } } return 0; }。

java实现约瑟夫环的实例代码

java实现约瑟夫环的实例代码
这篇文章主要给大家介绍了关于设计模式之责任链模式的概念实现以及netty中的责任链模式的相关资料文中通过示例代码介绍的非常详细对大家的学习或者工作具有一定的参考学习价值需要的朋友们下面随着小编来一起学习学习吧
java实 现 约 瑟 夫 环 的 实 例 代 码
复制代码 代码如下:
import java.io.BufferedInputStream; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Josephus {
pointer = pointer.next; i++; } //list.add(pointer.next.No); System.out.println("将序号"+pointer.next.No+"剔除。"); pointer.next=pointer.next.next; pointer=pointer.next; } System.out.println("这是最后一个人:"+pointer.No); } }
pointer.next = new Node(i); pointer = pointer.next; } pointer.next= header; pointer=header; while(pointer != pointer.next){ int i =2; while(i<cycleNum){
private static class Node{ int No; Node next; public Node(int No){ this.No=No; }

约瑟夫环c语言代码原创

约瑟夫环c语言代码原创
head2=creat2(head1);
p=head2;
while(p!=NULL)
{
printf("%d ",p->num);
p=p->next;
}
}
printf("输入初始m值\n");
scanf("%d",&m);
p1=p2=(struct outlist *)malloc(sizeof(struct outlist));
head1=p1;
p0=head;temp=NULL;
while(p0->next!=p0)
{
i=1;
while(i<m)
};
struct peolist *creat1()
{
int i=1;
struct peolist *head;
struct peolist *p1,*p2;
printf("依次输入个人的密码,输入非正数时结束\n");
p1=p2=(struct peolist *)malloc(sizeof(struct peolist));
scanf("%d",&p1->secret);
head=p1;
p1->n=i;
while(p1->secret>0)
{
i++;
p2=p1;
p1=(struct peolist *)malloc(sizeof(struct peolist));
scanf("%dቤተ መጻሕፍቲ ባይዱ,&p1->secret);
p1->n=i;

Python3下约瑟夫环的不同实现方式

Python3下约瑟夫环的不同实现方式

Python3下约瑟夫环的不同实现⽅式基于python的约瑟夫环思路⼀:递归# 约瑟夫环:递归def KillYuesefu(n,m):if(n == 1):return 0return (KillYuesefu(n - 1, m) + m ) % ndef main():for num in range(1,11):lastindex=KillYuesefu(num,8)+1print(lastindex)if __name__ == "__main__":main()思路⼆:单向链表# 约瑟夫环:单向循环链表class Node:def __init__(self,Id,NextNode):self.Id=Idself.NextNode=NextNodedef GenerateNodeLinkList(listLen):header = Node(1,None)tmpPreNode = headerif(listLen < 1 ):return Noneelif listLen>1:for i in range(2,listLen):tmpNode = Node(i,None)tmpPreNode.NextNode=tmpNodetmpPreNode=tmpNodereturn headerdef GenerateNodeLinkList_Yuesefu(n):# 初始化链表header = Node(1,None)tmpPreNode = headerif(n < 1 ):return Noneelif n > 1:for i in range(2 , n+1):tmpNode = Node(i,None)tmpPreNode.NextNode=tmpNodetmpPreNode=tmpNodetmpPreNode.NextNode=headerreturn headerdef KillYuesefu(nodelist,m):curIndex=1curNode=nodelistpreNode=Nonewhile(curNode!=preNode):if curIndex==m:# 杀死当前节点print("%d" % (curNode.Id),end=" --> ")curNode=curNode.NextNodepreNode.NextNode=curNodecurIndex=1else:curIndex=curIndex+1preNode=curNodeif curNode.NextNode is not None:curNode=curNode.NextNodeelse:breakprint("alive %d" % curNode.Id,end=" ")print("OVER")def main():for num in range(1,11):print("begin num is %d" % num)nodelist=GenerateNodeLinkList_Yuesefu(num)KillYuesefu(nodelist,8)if __name__ == "__main__":main()思路三:双向链表# 约瑟夫环:双向循环链表class Node:def __init__(self,Id,Name,PreNode,NextNode):self.Id=Id=Nameself.PreNode=PreNodeself.NextNode=NextNodedef GenerateNodeLinkList(listLen):header = Node(1,"Name1",None,None)tmpPreNode = headerif(listLen < 1 ):return Noneelif listLen>1:for i in range(2,listLen):tmpNode = Node(i,"Name-%d" % i,tmpPreNode,None)tmpPreNode.NextNode=tmpNodetmpPreNode=tmpNodereturn headerdef GenerateNodeLinkList_Yuesefu(n):# 初始化链表header = Node(1,"Name1",None,None)tmpPreNode = headerif(n < 1 ):return Noneelif n > 1:for i in range(2 , n):tmpNode = Node(i,"Name-%d" % i,tmpPreNode,None)tmpPreNode.NextNode=tmpNodetmpPreNode=tmpNodetmpPreNode.NextNode=headerheader.PreNode=tmpPreNodereturn headerdef KillYuesefu(nodelist,m):curIndex=1curNode=nodelistwhile(curNode is not None):if curIndex==m:# 杀死当前节点print("Id=%d,Name=%s" % (curNode.Id,),end=" --> ") tmp = curNode.PreNodeif tmp is None:# 前⾯没有节点了,结束breakcurNode=curNode.NextNodeif tmp==curNode:# 重叠,结束breaktmp.NextNode=curNodecurNode.PreNode=tmpcurIndex=1else:curIndex=curIndex+1curNode=curNode.NextNodeprint("OVER")def main():nodelist=GenerateNodeLinkList_Yuesefu(10)KillYuesefu(nodelist,6)if __name__ == "__main__": main()。

约瑟夫环

约瑟夫环

四、程序代码 (根据前面的思想分析,算法整理得到完整的可编译可调试的程序)源代码:#include <stdio.h> //输入输出函数头文件#include <stdlib.h> //字符串转短整形函数的头文件10140219 typedef struct LNode //定义单循环链表中节点的结构{int num;//编号int pwd;//passwordstruct LNode *next; //指向下一结点的指针 }LNode;/*构造结点*/LNode *createNode(int m_num,int m_pwd){LNode *p;p=(LNode *)malloc(sizeof(LNode)); //生成一个结点p->num=m_num; //把实参赋给相应的数据域p->pwd=m_pwd;p->next=NULL; //指针域为空return p; }/**创建循环链表**/void createList(LNode **ppHead,int n){ /*创建单向循环链表ppHead,人数个数为n,并输入每个人的密码值,若建立失败则生成头结点,让cur指向他,若建立成功则插入结点P,cur指向的数据元素为p,后续为"空"的节点,再把P插入循环链表ppHead中*/int i,m_pwd;LNode *p,*cur;//cur: 浮标指针for(i=1;i<=n;i++){printf("输入第%d个人的密码:",i);scanf("%d",&m_pwd); //输入持有密码p=createNode(i,m_pwd); //调用构造结点函数if(*ppHead==NULL) //如果头结点为空{ *ppHead=cur=p; //生成头结点,让cur指向他cur->next=*ppHead; //cur的指针域指向自身cur->next=*ppHead; //cur的指针域指向自身 }else //如果不为空,则插入节点{p->next = cur->next;cur->next = p; cur= p; //cur指向新插入结点} }printf("完成创建!\n"); //提示链表创建完成/*出队处理*/void jose(LNode *ppHead,int m_pwd){ /*p指向要删除节点的前一个节点,ppHead指向要删除的节点,使p=ppHead,ppHead 再指向要删除节点的下一个节点,使p和ppHead链接,输出p指向节点的编号和密码值,释放ppHead,如此循环,直至把所有节点都打印和删除为止!*/int i,j;LNode *p,*p_del; //定义指针变量for(i=1;p!=ppHead;i++){ for(j=1;j<m_pwd;++j){ p=ppHead; //p赋值为ppHead,p指向要删除结点的前一个结点ppHead=ppHead->next; //ppHead指向下一个元素}p->next = ppHead->next; //p结点与头结点链接i=ppHead->pwd; //i赋值为ppHead->pwdj=ppHead->num; //j赋值为ppHead->num,j为要删除的密码值printf("第%d个人出列,密码:%d\n",j,i);m_pwd=ppHead->pwd;//m_pwd赋值为ppHead->pwd free(ppHead);//释放头结点ppHead=p->next; //ppHead重新赋值给p->next,即释放前的ppHead->pwd指针//删除报数结点 }i=ppHead->pwd; //i赋值为ppHead->pwdj=ppHead->num; //j赋值为ppHead->numprintf("最后一个出列是%d号,密码是:%d\n",j,i); free(ppHead); //释放头结点 }void instruction(){printf("****************************************************************\n"); printf("约瑟夫环:\n");printf(" 编号为1,2,3,4…,n的n个人按顺时针方向围坐一圈,每人持有一个密\n");printf("码(正整数).一开始任选一个正整数作为报数的上限值m,从第一个人开始\n"); printf("按顺时针方向自1开始顺序报数,报到时停止.报m的人出列,将他的密码\n"); printf("m作为新的m值,从他在顺时针方向上的下一人开始重新从1报数,如此下去,\n");printf("直到所有人全部出列为止.编程打印出列顺序.\n");printf("******************************************************\n");return 0;}void menu(){printf("**************************约瑟夫环 *****************************\n"); printf(" \n");printf(" [1]约瑟夫环问题的阐述 \n");printf(" [2]按要求求解约瑟夫环 \n");printf(" [0]退出 \n");printf("************************** 欢迎使用! ****************************\n"); }/*主函数模块*/ int main(){ int n,m,x;LNode *ppHead=NULL; menu(); for(;;){printf("\n请选择要执行的操作:");scanf("%d",&x);system("cls");switch(x){case 1:printf("****************************************************************\n"); printf("约瑟夫环:\n");printf(" 编号为1,2,3,4…,n的n个人按顺时针方向围坐一圈,每人持有一个密\n");printf("码(正整数).一开始任选一个正整数作为报数的上限值m,从第一个人开始\n");printf("按顺时针方向自1开始顺序报数,报到m时停止.报m的人出列,将他的密码\n");printf("m作为新的m值,从他在顺时针方向上的下一人开始重新从1报数,如此下去,\n");printf("直到所有人全部出列为止.编程打印出列顺序.\n");printf("****************************************************************\n"); main();break;case 2:printf("\n请输入总人数n:");scanf("%d",&n);printf("请输入开始上限数m:");scanf("%d",&m);createList(&ppHead,n);printf("\n");printf("出队顺序:\n");jose(ppHead,m);printf("\n约瑟夫环游戏结束!\n");main();break;case 0:exit(0);default:system("cls");printf("\n您选择的操作有误,请重新选择...\n\n\n");main(); }}return 0; }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构课程设计实验学校:江西农业大学班级:软件1115班姓名:***学号:********课程:数据结构课程设计指导教师:***实验一:约瑟夫问题问题简述:约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。

从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

约瑟夫问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus问题。

改进约瑟夫问题的描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈, 每人有一个密码Ki(整数),留作其出圈后应报到Ki 后出圈。

报数方法采用顺时针报数和逆时针报数交替进行,初始密码可任意确定。

求最后剩下的人的编号。

这个就是约瑟夫环问题的实际场景,后来老师要求我们对要求中的每人所持有的密码以及第一次的报数上限值要用随机数产生。

因此约瑟夫环问题如果采用双向循环链表则能很好的解决。

循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。

p->link=head解决问题的核心步骤:先建立一个具有n个链结点,无头结点的循环链表,然后确定第一个报数人的位置,并不断地从链表中删除链结点,直到链表为空。

一、题目内容及要求【问题描述】编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

设计一个程序来求出出列顺序。

【要求】利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。

2)掌握线性表的基本操作,如插入、删除、检索等在链式存储结构上的运算。

二、实验环境(硬/软件要求):Windows XP +三、概要设计利用单向循环链表存储结构模拟此过程,因为循环链表最后一个结点的指针域指向头结点,整个链表形成一人环,刚好和题中的“n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)”内容要求一致,而且,循环链表中任一结点出发均可找到表中其他结点,利用这一优点可较容易地找出报数的人及下一个报数的人,最后按照出列的顺序用一个for语句实现。

循环链表的存储结构如下:struct Joseph 实践约瑟夫问题时的关键是用两个指针把一个移动的,一个指向要删除的节点,另外要注意保留头指针。

第一步是建立一个循环的单向链表。

第二步是运用指针遍历链表同时计数到第m个时将其删除。

此时指针指向不变。

其格式如下:void output(struct Joseph *head) //输出出列情况{int i,j=1;struct Joseph *p1,*p2;p1=p2=head; //p1 p2都指向头指针for(i=1;i<m;i++)p1=p1->next; //从第M个人开始报数,所以p1指针依次后移,指向第m个人while(n>0){for(i=1;i<s;i++){p2=p1;p1=p1->next; //开始报数,报到s前p1、p2依次后移}printf("第%d个出列的人是:%d\n",j,p1->num);p2->next=p1->next;p1=p2->next; //此人出列,将p1->next赋给p2->next,将p1所指向的结点删掉n--; //人数减少1j++; // 出列人数加1}}2创建单循环链表创建一个空单循环链表,双向循环链表和每个结点包括两个域:元素域和指针域。

形成单循环链表的原理:定义三个指针变量H,r,s,三指针开始全部指向头结点,在插入操作开始后,H不变仍指向头结点,s指针在插入过程中始终指向新插入的节点,而r指针紧随其后,用于将新插入的节点和前一个节点连接起来,最后通过r指向头指针H,来完成环的操作。

关键代码实现如下:if(H==NULL) { H=s,r=H;}//从链表的第一个节点插入else { r->next=s,r=s;//r后移}//链表的其余节点插入结束for循环后结成环的操作:r->next=H;/*生成循环单链表*/return H;3查找并删除节点每当结点计数到某一结点时,将他的前驱结点接到他的后继结点,然后将他的密码值cipher赋给计数变量,再将此结点删除。

如此循环下去,直到最后变为空的单循环链表为止。

函数通过代码:p=H;pre=p;p=p->next;pre->next=p->next;p=pre->next;来删除当前的那个结点q,通过循环来一次次删除当前的结点,直到链表中剩下最后一个结点。

五、程序清单/*运行环境VC*/#include <>#include<>#include <>#define LEN sizeof(struct Joseph)struct Joseph //定义joseph{int num;struct Joseph *next;};int n,s,m;void print(struct Joseph *head) //打印链对中的信息{struct Joseph *p; //p指针p=head; //将p指向头指针printf("%d个人的代号如下:\n",n);do{printf("%d ",p->num);p=p->next;}while(p!=head); //依次输入每个人的代号printf("\n");}void output(struct Joseph *head) //输出出列情况{int i,j=1;struct Joseph *p1,*p2;p1=p2=head; //p1 p2都指向头指针for(i=1;i<m;i++)p1=p1->next; //从第M个人开始报数,所以p1指针依次后移,指向第m个人while(n>0){for(i=1;i<s;i++){p2=p1;p1=p1->next; //开始报数,报到s前p1、p2依次后移}printf("第%d个出列的人是:%d\n",j,p1->num);p2->next=p1->next;p1=p2->next; //此人出列,将p1->next赋给p2->next,将p1所指向的结点删掉n--; //人数减少1j++; // 出列人数加1}}struct Joseph *create() //建立链队列{int i;struct Joseph *head;struct Joseph *p1,*p2;printf("请输入总人数(输入0退出程序):\n"); scanf("%d",&n);if(n==0)exit(0);//退出for(i=1;i<=n;i++){p1=(struct Joseph*)malloc(LEN);p1->num=i;if(i==1)head=p1;elsep2->next=p1;p2=p1;}p2->next=head; //将整个链队构成一个环形print(head);printf("请输入从第几个人开始报数:\n"); scanf("%d",&m);printf("数到第几个人出列:\n");scanf("%d",&s);return head;}main(){struct Joseph *head;while(1){head=create();output(head);system("pause");system("cls");}}六、运行结果七、实验心得在约瑟夫问题中,着重训练的是链表的应用,尤其是链表中结点的删除、检索等。

由于单向链表等线性表的操作基本思想是一致的,因此通过对单向链表的练习来加深对线性表的理解。

在本实验中,需要解决的问题的重点是怎样找到要删除的结点。

因此,我首先考虑解决这个问题,即应用循环语句来找到满足条件的结点,我选用了if循环语句。

然后应用指针实现查找过程。

在弄清出这些之后,在建立一个单向链表即形成程序。

在经过调试改正一些细节即可。

在编辑的过程中,将所学的知识充分应用于实践,虽然遇到了一些问题,比如说不知从何下手,不过通过仔细考虑找出问题的关键和参考资料并逐步编辑出程序。

从而注意到了一些细节问题,例如:头指针的问题、*p1,*p2之间在不同的函数中不同的关系的区分以及函数位置的前后和声明的关系等等。

这些只有在真的去实践时才能意识到的小问题给我带来了很大的困惑。

这次的实验让我重新熟悉了C++的编辑环境,为以后的实验奠定了基础。

相关文档
最新文档