约瑟夫环问题-数据结构实现代码

合集下载

数据结构课程设计——约瑟夫环报告(含代码)

数据结构课程设计——约瑟夫环报告(含代码)

#include<stdio.h>#include<stdlib.h>typedef struct LNode{//数据域int cipher; //密码int number; //编号struct LNode *next; //指针域}LNode,*LinkList;void InitList(LinkList &L) //创建一个只有头结点链表{L = (LinkList)malloc(sizeof(LNode));if(!L){exit(1);printf("/n/nError!/n/n");}L->next = L;}void CreateList(int n,LinkList &L) //初始化循环单链表{LinkList p,q;q = L;printf("分别输入每个人的密码:");for(int i = 1;i <= n;i++){int k;scanf("%d",&k);if(k <= 0){printf("\n\n密码有误!\n\n");exit(1);}p = (LinkList)malloc(sizeof(LNode));if(!p){exit(1);printf("/n/nError!/n/n");}p->cipher = k;p->number = i;L->next = p;L = p;}L->next = q->next;free(q);}void PrintList(int x,int n,LinkList L) //输出出列顺序{LinkList p,q;p = L;for(int i = 1;i <= n;i++){for(int j = 1;j < x;j++)p = p->next;q = p->next;x = q->cipher;printf("%d ",q->number);p->next = q->next;free(q);}}int main(){printf("=============约瑟夫环==============\n\n\n");int n,x;LinkList L;L = NULL;InitList(L); //构造空链表printf("输入初始密码:");scanf("%d",&x); //初始密码为xprintf("\n");printf("输入参与总人数:");scanf("%d",&n); //总共的人数nprintf("\n");CreateList(n,L); //建立好一个约瑟夫环printf("\n\n\n===================================\n\n");printf("出列编号为:");PrintList(x,n,L); //输出出列顺序printf("\n\n");return 0;}。

C++单链表实现约瑟夫环

C++单链表实现约瑟夫环

#include <iostream.h>#include <stdlib.h>struct Member//定义结构体{int number;int password;Member *next;};class Joseph{public:Member *frist;//头指针int size;Joseph(void);~Joseph(void);int Size(void) const;//返回长度Member *Index(int i);//定位void Create(int i);//构造循环单链表int Delete(int i);//删除结点并返回number的值};Joseph::Joseph(){//frist=new Member;Member *p=new Member;frist=p;size=0;}Member *Joseph::Index(int i){if(i==0)return frist;Member *p=frist->next;int j=1;while(j<i){p=p->next;j++;}return p;}int Joseph::Size(void)const{return size;}void Joseph::Create(int i){for(int j=1;j<=i;j++){Member *p=Index(j-1);Member *q=new Member;q->number=j;p->next=q;size++;};//Member *p=Index(i);//p->next=frist;}Joseph::~Joseph(void){Member *p,*q;p=frist;while(size!=0){q=p;p=p->next;delete q;size--;}size=0;frist=NULL;}int Joseph::Delete(int i){Member *s,*p=Index(i-1);s=p->next;p->next=p->next->next;int x=s->number;cout<<x<<" ";int y=s->password;delete s;size--;return y;}void main(void){Joseph jos;int i;cout<<"Please input number of people :"<<endl;cin>>i;jos.Create(i);int frist;//设初始值cout<<"Please input the frist number :"<<endl;cin>>frist;for(int k=1;k<=i;k++)//用循环输入每个人的密码{cout<<"please input No."<<k<<"`s password:"<<endl;Member *b=jos.Index(k);cin>>b->password;}cout<<"The final is :"<<endl;int l=frist%i;if (l==0) l=i;for(int b=i-1;b>0;b--){frist=jos.Delete(l);l=(frist+l-1)%b;int e=jos.Size();if(l==0)l=e;}jos.Delete(l);cout<<endl;}。

C++编写的 约瑟夫环问题 代码

C++编写的 约瑟夫环问题 代码

程序源代码:#include <stdio.h>#include <malloc.h>#include<conio.h>#include <stdlib.h>#include<ctime>#define NULL 0typedef struct Node{int m;//密码int n;//序号struct Node *next;}Node,*Linklist;Linklist create(int z) //生成循环单链表并返回,z为总人数{int i,mm;Linklist H,r,s;H=NULL;printf("请按顺序依次为每个人添加密码:");for(i=1;i<=z;i++){printf("\ninput cipher=");scanf("%d",&mm);s=(Linklist)malloc(sizeof(Node));s->n=i;s->m=mm;printf("%d号的密码%d",i,s->m);if(H==NULL)//从链表的第一个节点插入{H=s;r=H;}else//链表的其余节点插入{r->next=s;r=s;//r后移}//for结束r->next=H;/*生成循环单链表*/return H;}void search(Linklist H,int m0,int z)//用循环链表实现报数问题{int count=1;//count为累计报数人数计数器int num=0;//num为标记出列人数计数器Linklist pre,p;p=H;printf("出列的顺序为:");while(num<z){do{count++;pre=p;p=p->next;}while(count<m0);{pre->next=p->next;printf("%d ",p->n);m0=p->m;free(p);p=pre->next;count=1;num++;}//while结束}void clean(){int system(const char *string);int inquiry;printf("请问需要清除上一次操作记录吗(1.清屏/2.不清屏)...?\n"); scanf("%d",&inquiry);if(inquiry ==1)system("cls");}void text(){int m0,z,i, choose,k=1; //k用来阻止第一次进入程序清屏操作Linklist H;bool chooseFlag=false;while(1){if(k!=1)clean();k++;while(!chooseFlag){printf(" ……………………欢迎进入约瑟夫环问题系统…………………… \n"); printf( "* 1.输入约瑟夫环数据 * \n"); printf(" * 2.什么是约瑟夫环 * \n"); printf(" * 3.退出系统 * \n"); printf("........................................................ \n"); printf("请输入相应的数字进行选择: ");scanf("%d",&choose);for(i=1;i<=4;i++){if(choose==i) { chooseFlag=true; break;}else chooseFlag=false;}if(!chooseFlag) printf("Error Input!\n");} //end while(!chooseFlag)if(choose==1) //if 开始{printf("Input how many people in it:");//z为总人数scanf("%d",&z);if(z<=30){H=create(z);//函数调用printf("\nInput the start code m0=");scanf("%d",&m0);search(H,m0,z);printf("\n\n\n");}else{printf("超过最大输入人数\n");break;}}else if(choose==2){printf("\n约瑟夫环问题:设有n个人,其编号分别为1,2,3,…,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);}}实验体会:通过对本问题的分析,我进一步熟悉了对各种逻辑表达式的判断和指针的使用。

python编程练习---约瑟夫环

python编程练习---约瑟夫环
10个人按110进行编号围成一圈从1开始报错报到7的出队下一个人从1开始重新报数问最终剩下的人的编号
python编程练习 ---约瑟夫环
游戏:10个人按1-10进行编号,围成一圈,从1开始报错,报到7的出队,下一个人从1开始重新报数,问最终剩下的人的编号
这个游戏是一个约瑟夫环问题,我们可以采用队列的形式来完成
from collections import deque
def jsonf(target, list): #target目标值,list人员
dq = deque(list)
#存入双端队列
index = 0
#初始化标记
while len(dq) > 1: #循环终止条件为剩余1个人
temp = dq.popleft() #头部出队
index += 1
#标记值自增
if index == target: #标记值等于target
index = 0 #归零
continue
#下一轮
else:
#标记值不等于target
dq.append(temp) #头部出队的人从尾部入队
retu

约瑟夫环 源代码

约瑟夫环  源代码

#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;}。

约瑟夫问题的C++代码

约瑟夫问题的C++代码

#include<iostream>using namespace std;struct Node//定义节点的结构类型{int data;Node* next;};class CircularLinkedList//循环链表类{public:CircularLinkedList(){first=new Node;first->next=NULL;}CircularLinkedList(int n);//构建一个附有值的循环链表~CircularLinkedList();int Josephus(int num);//约瑟夫函数private:Node* first;};CircularLinkedList::CircularLinkedList(int n){first=new Node;Node * r=first;for(int i=1;i<=n;i++){Node* s=new Node;s->data=i;s->next=NULL;r->next=s;r=s;} //头插法初始化链表r->next=first; //最后一个元素的next志指向头结点}CircularLinkedList::~CircularLinkedList(){Node* p=first,*q;while(p->next!=first)//p指向最后一个结点时结束循环{q=p;p=p->next;delete q;}delete p;//删除头结点}int CircularLinkedList::Josephus(int num){Node* p=first,*q;if(num<=0)throw "输入错误!";while(first->next->next!=first){for(int i=1;i<num;i++) //p向后移动num位,指向要删除的元素的前一个结点{p=p->next;if(p==first) //若循环过程中出现p指向头结点,则跳过头结点{p=p->next;}}if(p->next==first) //若循环结束后p指向最后一个元素,则要跳过头结点,并让头结点的next指向要删除元素的下一个{p=first;q=p->next;p->next=q->next;//first->next=q->next;cout<<q->data<<" ";delete q;}else{q=p->next;p->next=q->next;cout<<q->data<<" ";delete q;}}cout<<endl;cout<<"最后一个数为:";return first->next->data;}void main(){int n,m;cout<<"请输入约瑟夫问题的人数和间隔人数:";cin>>n>>m;cout<<"依次删除:"<<endl;CircularLinkedList Josephus1(n);//创建的对象调用第二个构造函数cout<<Josephus1.Josephus(m)<<endl;}。

数据结构与算法(Python版):用队列(Queue)处理约瑟夫问题

数据结构与算法(Python版):用队列(Queue)处理约瑟夫问题

数据结构与算法(Python版):⽤队列(Queue)处理约瑟夫问题在古罗马时期,犹太⼈背叛了罗马⼈,落到困境,约瑟夫和同⾏的⼀共39个犹太⼈只能够⾃杀殉国,但是犹太教义规定不能⾃杀,因此只能够让别⼈将⾃⼰杀害。

他们所有39个⼈坐成⼀圈,报数1—7,报到7则由⾝旁的⼈将⾃⼰杀死。

结果约瑟夫灵机⼀动,给⾃⼰安排了⼀个位置,最后活了下来,那么约瑟夫给⾃⼰安排的是哪⼀个位置呢?在这个题⽬当中,我们如果使⽤队列,不仅可以处理任意⼈数坐成⼀圈,还可以将报数的值任意修改,最后都可以找到那⼀个不被杀死的⼈的位置。

我们可以将所有⼈都放进⼀个⼤的队列⾥,每报⼀次数字,那么就把队列头部的⼈放到队列的尾部,直到报数报到⼀组数字的最后⼀个,⽐如1——7当中的7。

这个时候就将队列头的这个⼈删除(也就是杀死),不断执⾏这个过程,直到整个队列当中的⼈数只有⼀个,则跳出循环返回最后活着的那个⼈的名字。

⾸先定义队列(Queue)类的结构:class Queue():def__init__(self):# 初始化⼀个空的列表self.__list=[]# 往队列⾥插⼊元素def enqueue(self,item):self.__list.append(item)# 弹出队列⾥的元素def dequeue(self):return self.__list.pop(0)# 弹出队列⾥最先进⼊的元素# 判断队列是否为空def is_empty(self):return self.__list == []# 计算队列的⼤⼩def size(self):return len(self.__list)使⽤队列类来初始化⼀个对象,sim_queue,然后编写刚才我们分析之后的程序:def hot_potato(namelist,num):sim_queue = Queue()for name in namelist:sim_queue.enqueue(name) # 把拿到的名字全部都放到队列⾥while sim_queue.size() > 1:for i in range(num):sim_queue.enqueue(sim_queue.dequeue())# 每执⾏完⼀次,就将队列的头拿出来弹出,相当于⼟⾖传递给这个⼈,然后这个⼈就死了last_person=sim_queue.dequeue()return last_personprint("开始执⾏约瑟夫问题")print(hot_potato(["bob","NAni","Ao li Gei!","HeHe","Mike","Suvennia"],4))输出:开始执⾏约瑟夫问题Ao li Gei!得解,因此Ao li Gei!这个⼈不会被杀死。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for(i=1;i<=n;i++)
SCLLInsert(head,i,test[i-1]);
JesephRing(head,m,n);
printf("\n\n");
}
若j=-1,则表示下标从0开始,要插入结点序号i表示第i-1个结点*/
while(p!=head&&j<i-1)
{
p = p->next;
j++;
}
if(j!=i-1&&i!=1) /*此时头结点的序号为1,
为了保证不在头结点处或头结点前进行任何操作*/
{
printf("插入位置参数错!");
return 0;
(*head)->next = *head;
}
int SCLLInsert(SCLNode *head,int i,DataType x)//插入节点
{
SCLNode *p,*q;
int j;
p = head->next;
j =1; /*表示结点(头结点)下标从1开始,即要插入结点的序号i就表示第几个结点
j+&
printf("取元素位置参数错!");
return 0;
}
*x = p->data;
return 1;
}
int SCLLNotEmpty(SCLNode *head)//判断链表非空否
{
if(head->next == head)
return 0; //为空返回0
else
{
SCLNode *p,*q;
int j;
p = head; j=0;
while(p->next!=head&&j<i-1)
{
p = p->next;
j++;
}
if(j!=i-1)
{
printf("删除位置参数出错");
return 0;
}
q = p->next;
p->next = p->next->next;
{
SCLNode *q=p->next;
p->next=p->next->next;
free(q); //将链表中断开后的节点,即要删除的节点从内存中释放
}
void JesephRing(SCLNode *head,int m,int n)
/*带头结点循环单链表head,初始报数值为m的约瑟夫环问题函数*/
for(i=0;i<j;i++)
{
printf(" %d ",a[i]);
}
}
void main()
{
DataType test[7]={{1,1},{2,10},{3,7},{4,2},{5,9},{6,8},{7,6}};
int n=7,m=20,i;
SCLNode *head;
SCLLInitiate(&head);
curr=curr->next;
if(curr==head)
curr=curr->next;
SCLLDeleteAfter(pre);
}
/*分别输出a[i]和b[i]*/
printf("约瑟夫环的先后出列顺序为:");
for(i=0;i<j;i++)
{
printf(" %d号",b[i]);
}
printf("\n\n各出列序号所对应的密码:");
以下是约瑟夫环问题的实现代码:由两部分组成jeseph.h文件和jesephMain.c文件
jeseph.h文件如下:
/*自定义DataType数据类型*/
typedef struct
{
int number;//每个人所对应的序号
int cipher;//每个人手中的密码
} DataType;
/*构造循环单链表结点数据类型,包括个人信息及结点间的相互关系*/
if(curr==head)
{
pre=curr;
curr=curr->next;
}
}
/*将出列约瑟夫环数的序号及其所对应的密码放在b[],a[]中*/
b[j]=curr->data.number;
a[j]=curr->data.cipher;->data.cipher;
return 1; //非空返回1
}
jesephMain.c文件如下:
#include<stdio.h>
#include<stdlib.h>
#include"jeseph.h" /*包含jeseph抽象数据类型*/
void SCLLDeleteAfter(SCLNode *p)//删除p指针所指结点的下一个结点
*x = q->data;
free(q);
return 1;
}
int SCLLGet(SCLNode *head,int i,DataType *x)//获取链表中指定位置的结点
{
SCLNode *p;
int j;
p = head;
j = 0;
while(p->next!=head&&j<i)
{
p = p->next;
{
SCLNode *pre,*curr;
int i,j=0;
int a[n],b[n];//n表示约瑟夫环数的个数
pre=head;
curr=head->next;
while(SCLLNotEmpty(head)==1)
{
for(i=1;i<m;i++)
{
pre=curr;
curr=curr->next;
typedef struct node
{
DataType data;
struct node *next;
}SCLNode;
void SCLLInitiate(SCLNode **head)//初始化链表
{
if((*head = (SCLNode *)malloc(sizeof(SCLNode)))==NULL) exit(1);
}
if((q = (SCLNode *)malloc(sizeof(SCLNode)))==NULL) exit(1);
q->data = x;
q->next = p->next;
p->next = q;
return 1;
}
int SCLLDelete(SCLNode *head,int i,DataType *x)//删除一个指定位置的结点
相关文档
最新文档