约瑟夫环的JAVA实现以及对应的代码讲解

合集下载

约瑟夫环代码

约瑟夫环代码

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

约瑟夫环问题讲解

约瑟夫环问题讲解

2009年02月24日星期二下午 05:03问题描述:约瑟夫环问题;有N个人围成一个环,从第一个人开始报数,报到M 的人退出环,并且由他的M值来代替原有的M值,要求输出离开环的顺序。

#include<iostream>#include<stdlib.h>using namespace std;//结点中数据域的类型定义typedef struct{int number;//标号int chipher;//手中的值}DataType;//带头结点的单循环链表typedef struct node{DataType data;struct node *next;}Scnode;//初始化void MyInit(Scnode **head)//指向指针的指针。

{if((*head=(Scnode *)malloc(sizeof(Scnode)))==NULL) exit(1);//动态分配 (*head)->next=*head;}//插入int MyInsert(Scnode *head,int i,DataType x){Scnode *p,*q;int j;p=head->next;j=1;while(p->next!=head&&j<i-1){p=p->next;j++;}if(j!=i-1&&i!=1){cout<<"erro!!!!!!!!!";return 0;}if((q=(Scnode *)malloc(sizeof(Scnode)))==NULL) exit(1); q->data=x;q->next=p->next;p->next=q;return 1;}//删除int MyDelete(Scnode *head,int i,DataType *x){Scnode *p,*q;int j;p=head;j=1;while(p->next!=head&&j<i-1){p=p->next;j++;}if(j!=i-1){cout<<"erro!!!!!!!!!";return 0;}q=p->next;*x=q->data;p->next=p->next->next;free(q);return 1;}//取数据元素int MyGet(Scnode *head,int i,DataType *x){Scnode *p;int j;p=head;j=0;while(p->next!=head&&j<i){p=p->next;j++;}if(j!=i){cout<<"erro!!!!!!!!!";return 0;}*x=p->data;return 1;}//判断是否为空int MyNotEmpty(Scnode *head){if(head->next==head) return 0;else return 1;}//删除P结点所指结点的下一个结点(也就是下面函数中的pre结点的下一个结点) void MyDelete(Scnode *p){Scnode *q=p->next;p->next=p->next->next;free(q);}//关键的函数void MyRing(Scnode *head,int m){Scnode *pre,*curr;int i;pre=head;curr=head->next;while(MyNotEmpty(head)==1)//这个喜欢是外层的把人循环完{for(int i=1;i<m;i++)//注意此处的循环是把当前m值下的人找出来。

约瑟夫环

约瑟夫环

软件综合课程设计约瑟夫环串的查找和替换二〇一四年六月一、约瑟夫环1.问题陈述编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。

一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。

要求:1、利用单循环链表作为存储结构模拟此过程;2、键盘输入总人数、初始报数上限值m及各人密码;3、按照出列顺序输出各人的编号。

2.程序代码#include<iostream>using namespace std;#include<malloc.h>typedef struct node{int number;int key;struct node* next;}listnode, * circularlist;//定义了结点类型listnode和指针类型circularlistint main(){int amount,t,code,m,k;circularlist w=(listnode*)malloc(sizeof(listnode));w->next=w;listnode *v;cout<<"请输入总人数:";cin>>amount;v=w;for(k=1;k<=amount;k++){cout<<"请输入第"<<k<<"个学生的密码:" ;cin>>code;w->key=code;w->number=k;if(k!=amount){w->next=(listnode*)malloc(sizeof(listnode));w=w->next;}w->next=v;}cout<<"约瑟夫环已建成,可以开始!"<<endl;cout<<"请输入初值:";cin>>m;if(m<=0){cout<<"输入错误,请重新输入"<<endl;return(1);}m=m-1;cout<<"出列顺序是:";do{t=0;//加入m减1后为零的情况while(t!=m){w=w->next;t++;}v=w->next;w->next=v->next;cout<<v->number<<"\t";m=v->key;m=m-1;free(v);}while(w->next!=w);cout<<w->number;free(w);getchar();getchar();return(0);}3.运行结果4.设计体会与总结看到这个题目后,我碰到的第一个问题是:什么是约瑟夫环?根据题目的描述,我自己先用5个数字进行了实验,直到了解它的过程和步骤之后才开始进行模块划分。

项目03 解决约瑟夫环问题

项目03 解决约瑟夫环问题

模块1
知识要点
定义数组应注意事项:
数组的使用
1) 定义数组时不要漏写数组长度。
2) 数组中存储的数据称为数组元素。
3) 不管数组中含有多少个元素,该数组都只有一个名 称,即数组名称。 4) 数组的下标范围从0到(数组长度-1),如果超过这个 范围,就会造成数组越界。
数组元素初始值见表3-2。
模块1
模块1
三、操作流程
(3) 编写代码: package demo;
数组的使用
/*
*一个简单的数组应用 */ import java.util.*; public class OneDemo
模块1
三、操作流程
数组的使用
public static void main(String[] args) { /* 声名变量 */
for(int i=0;i<a2.length;i++)
for(int j=0;j<a2[i].length;j++) for(int k=0;k<a2[i][j].length;k++){
模块1
知识要点
语法: 数据类型 数组名[ ]=new
数组的使用
数据类型[数组长度];
模块1
知识要点
(3) 赋值。
数组的使用
有了空间就可以向数组的格子里存放数据了。
语法:
数组名[下标值]=值;
模块1
知识要点
例如:
数组的使用
score[0]=89;
score[1]=56; score[2]=75; „ 这样赋值写起来非常的麻烦,观察代码每一次都是在使
模块1
知识要点

约瑟夫环-数据结构

约瑟夫环-数据结构

实验二:Joseph(约瑟夫环)实验报告实验描述:编号为1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(报数上限)。

任意输入一个正整数作为报数上限值k(1<=k<=n),从第一个人开始顺时针方向报数,报到k时停止报数。

报k的人出列,然后从他下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

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

实验原理:先构造一个不带头结点的单循环链表,然后定义两个节点指针,第一个指针指向第一个节点,另一个指针指向第二个节点,并且使两个节点后移,每当结点计数到某一结点时,将他的前驱结点接到他的后继结点,再将此结点删除。

如此循环,直到两个节点重合(只有一个节点)时,循环结束。

实验过程:1.基本算法以及分析:1创建结点Node链表都是由一个个结点组成,由于结点的不同,组成的链表也不同。

因此需要创建链表结点。

结点结构体如下:2建立单循环链表每当结点计数到某一结点时,将他的前驱结点接到他的后继结点,再将此结点删除。

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

3程序的执行过程:程序有主函数开始,首先输入创建约瑟夫环节点数以及密码(报数上限)。

然后,开始调用JosephuNode *Creat_Node函数,利用单循环链表建立起约瑟夫环,函数结尾return head; 将约瑟夫环的头指针返回,并将它赋值head,然后主函数继续调用Josephu函数,通过将head和Password引入函数,以建立两个嵌套循环输出并得到结果。

2.程序源代码:#include <stdio.h>#include <malloc.h>typedef struct Node{int Index;struct Node *next;}JosephuNode;void main(){JosephuNode *Creat_Node(int numbers);void Josephu(JosephuNode *head,int Password);int numbers, Password;JosephuNode *head;printf("\n输入约瑟夫环问题的人数和起始密码:");scanf("%d,%d", &numbers, &Password);head=Creat_Node(numbers);printf("\n输出结果如下\n");Josephu(head,Password);}JosephuNode *Creat_Node(int numbers) // 使用单循环链表创建约瑟夫环{int i,pass;JosephuNode *head, *tail;head = tail = (JosephuNode *)malloc(sizeof(JosephuNode)); //申请头结点for (i = 1; i <numbers; i++){tail->Index = i;tail->next = (JosephuNode *)malloc(sizeof(JosephuNode));tail = tail->next; //指针指向下一个结点}tail->Index = i;tail->next = head; //建立循环return head;}void Josephu(JosephuNode *head,int Password) //数据结构{int i,j;JosephuNode *rear;for (i = 1; rear != head; i++){for (j = 1; j <Password; j++){rear = head;head = head->next;}rear->next = head->next;printf("\n第%d个出局的人的编号是:%d",i,head->Index);free(head);head = rear->next;}j=head->Index;printf("\n最后一个出局的人的编号是:%d\n ",j);free(head);}。

约瑟夫环-数据结构

约瑟夫环-数据结构

数据结构期末试验报告学院:专业:学号:班级:姓名: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个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

循环链表实现原理及运用约瑟夫环实例

循环链表实现原理及运⽤约瑟夫环实例package mainimport "fmt"type LinkNode struct {Data interface{}Next *LinkNode}//创建循环链表func (node *LinkNode) Create(Data ...interface{}) {if node == nil {return}if len(Data) == 0 {return}//记录头节点head := nodefor _, v := range Data {//创建⼀个新节点newNode := new(LinkNode)newNode.Data = v//当前节点的下⼀个节点为新节点node.Next = newNodenode = node.Next}//形成闭环//最后⼀个节点的下⼀个节点为第⼀个节点node.Next = head.Nextnode = head}//打印循环链表func (node *LinkNode) Print() {if node == nil {return}//记录循环链表的起始点start := node.Next//打印链表for {node = node.Nextif node.Data != nil {fmt.Print(node.Data, " ")}if start == node.Next {break}}// 单向链表打印⽅式//for node.Next != nil {// if node.Data != nil {// fmt.Println(node.Data)// }// node = node.Next//}}//循环链表长度返回值个数func (node *LinkNode) Length() int {if node == nil {return -1}//记录循环链表的起始点start := node.Next//定义计数器i := 0for {node = node.Nexti++if start == node.Next {break}}return i}//插⼊数据(下标数据)func (node *LinkNode) Insert(index int, Data interface{}) { if node == nil {return}//判断位置是否越界if index < 0 || node.Length()+1 < index {return}if Data == nil {return}fmt.Println(node)//记录链表第⼀个节点start := node.Next//记录上⼀个节点preNode := nodefor i := 0; i < index; i++ {preNode = nodenode = node.Next}//创建新节点newNode := new(LinkNode)newNode.Data = Data//新节点的下⼀个节点为nodenewNode.Next = node//上⼀个节点的下⼀个节点为新节点preNode.Next = newNode//判断如果是第⼀个节点需要将最后⼀个节点指向新节点 if index == 1 {for {//判断最后⼀个节点if start == node.Next {break}node = node.Next}//新节点为最后⼀个节点的下⼀个节点node.Next = newNode}}//删除数据(下标)func (node *LinkNode) Delete(index int) {if node == nil {return}if index < 0{return}//起始节点start := node.Next//记录上⼀个节点preNode := node//循环找到删除数据的位置for i := 0; i < index; i++ {preNode = nodenode = node.Next}//判断如果删除的是第⼀个节点if index == 1 {//temp记录最后⼀个位置temp := startfor {if start == temp.Next {break}temp = temp.Next}//将最后⼀个节点指向新节点temp.Next = node.Next}//删除数据preNode.Next = node.Next//数据销毁//node.Data = nil//node.Next = nilnode = nil}//约瑟夫环//运⽤ -- 海盗分⾦func main() {list := new(LinkNode)list.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32) fmt.Println("原始数据:")list.Print()fmt.Println()fmt.Println("删除数据:")i := 1for list.Length() > 2 {i += 3if i > list.Length() {i = list.Length()%3 + 1}list.Delete(i)list.Print()fmt.Println()}}。

约瑟夫环

约瑟夫环实验报告一.需求分析在建立双向循环链表时,因为约瑟夫环的大小由输入决定。

为方便操作,我们将每个结点的数据域的值定为生成结点时的顺序号和每个人持有的密码。

进行操作时,用一个指针current指向当前的结点,指针front 始终指向头结点。

然后建立双向循环链表,因为每个人的密码是通过rand()函数随机生成的,所以指定第一个人的顺序号,找到结点,不断地从链表中删除链结点,直到链表剩下最后一个结点,通过一系列的循环就可以解决改进约瑟夫环问题。

二.概要设计1、循环链表抽象数据类型定义2、本程序包含一下几个模块(1)构造结点模块(2)创建链表模块(3)出队处理模块(4)约瑟夫环说明输出模块(5)菜单模块(6)主函数模块三.详细设计程序设计如下:#include<stdio.h>#include<stdlib.h>#include<malloc.h>typedef struct _node{struct _node* next;int number;}node,*linklist;linklist create(int n);void joseph(linklist head,int k,int m);int main(){linklist head;int m, n, k;printf("please input n:");scanf("%d",&n);printf("please input m:");scanf("%d",&m);printf("please input k:");scanf("%d",&k);head = create(n);printf("the sequences of leaving the list are:");joseph(head,k,m);return 0;}linklist create(int n){linklist head = (linklist)malloc(sizeof(node));node *tail;int i;head->next = head;head->number = 1;tail = head;for(i=2;i<=n;i++){node *p = (node*)malloc(sizeof(node));p->number = i;p->next = tail->next;tail->next = p;tail = p;}return head;}void joseph(linklist head, int k, int m) {int j;node *p;node*q;if(m== 1 && k == 1){p= head;while(p->next!=head){printf("%d?",p->number);q=p->next;free(p);p=q;}printf("%d\n",p->number);}else if(m==1&&k!=1){p=head;for(j=1;j<k-1;j++)p=p->next;while(head->next!=head) {q=p->next;p->next=q->next;printf("%d",q->number);if(q==head)head=q->next;free(q);}printf("%d\n",head->number); }else{p=head;for(j=1;j<k;j++)p=p->next;while(head->next!=head) {for(j=1;j<m-1;j++)p=p->next;q=p->next;p->next=q->next;printf("%d",q->number);if(q==head)head=q->next;free(q);p=p->next;}printf("%d\n",head->number);}}四.调试分析本次课程设计采用数据抽象的程序设计方法,将程序划分为三个层次结构:元素节点、单向循环链表,主控制模块。

数据结构约瑟夫环问题

数据结构实验报告题目:约瑟夫环问题一.设计内容[问题描述]约瑟夫环问题的一种描述是:编号为1, 2, 3,…,n的n个人按顺时针方向围坐一圈,每人手持一个密码(正整数)。

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

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

试设计程序实现之。

[基本要求] 利用循环链表存储结构模拟此过程,按照出列的顺序打印各人的编号。

[ 实验提示] 程序运行后首先要求用户指定初始报数上限值。

然后读取各人的密码。

设n<=30 。

程序执行后,要求用户在计算机终端上显示“提示信息”后,用键盘输入“提示信息”中规定的命令,以“回车符”为结束标志。

相应的输入数据和运算结果显示在其后。

二、设计目的1. 达到熟练掌握C++ 语言的基本知识和技能;2. 能够利用所学的基本知识和技能,解决简单的面向对象程序设计问题。

3. 把课本上的知识应用到实际生活中,达到学以致用的目的。

三、系统分析与设计(确定程序功能模块)1、为实现上述程序的功能,应以有序链表表示集合。

基本操作:InitList(&L)操作结果:构造一个空的有序表L。

DestroyList(&L)初始条件:有序表L 已存在。

操作结果:销毁有序表L。

ListEmpty(L)初始条件:有序表L 已存在。

操作结果:若L为空表,则返回TRUE,否则返回FALSE。

ListLength(L)初始条件:有序表L 已存在。

操作结果:返回L 中数据元素个数。

GetElem(L,i)初始条件:有序表L已存在,并且K i< ListLength(L)。

操作结果:返回L 中第i 个数据元素。

LocatePos(L,e)初始条件:有序表L已存在,e和有序表中元素同类型的值。

操作结果:若L中存在和e相同的元素,则返回位置;否则返回0。

实验报告约瑟夫环

实验报告
约瑟夫环
题目内容
编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。现在给定一个随机数 m>0,从编号为1的人开始,按顺时针方向1开始顺序报数,报到m时停止。报m的人出圈,同时留下他 的密码作为新的m值,从他在顺时针方向上的下一个人开始,重新从1开始报数,如此下去,直至所有的 人全部出圈为止。
添加节点的操作,添加此元素至链表尾部
void inilinklist(linklist *&l,int n){ l = (linklist*)malloc (sizeof (linklist)) ;
l->next = l; l->data = n; l->nu = 1;
return ; }
创建linklist的操作,使data为节点的位数,nu为密码数,此链表没有头节点,并且为循环链表,使首节 点指向尾部。
linklist *s; s=l; sd(l,f); return 0;
} 主函数,输出结果
void addnode(linklist *l,int num){ linklist *p; linklist *m; m=l; int k=2; p=(linklist*)malloc (sizeof(linklist));
p->data=num; while(m->next!=l){
m=m->next; k++; } p->nu=k; m->next=p; p->next=l; return; }
void dle(linklist *l,linklist *p){ linklist *k; k=l; while(k->next!=p){ k=k->next; } k->next=p->next; return ;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

约瑟夫环的JAVA实现以及对应的代码讲解
1.创建一个节点类Node

2.创建第一个节点Node(1)同时,建立一个搜索指针X
3.利用因为循环对节点进行初始化
以下是i =2时,x指针的指向:
当i=2时,创建Node(2)节点,同时x的next指向2,完成对2的初
始化之后,搜索指针后移指向2,直到全部完成初始化

12x11x12

x
4.开始出列,条件是只留下最后一个人
假设每到第三个人就出列
for循环指示,之前x指向1,不操作,x指向2,此时打印x的next
即第三个,并将x的next移除。

123x4
x

c.x.next=x.next.next
b.x=x.next
a.原始状态

a
b

c

While循环完成之后就只剩下最后一个人了。
以下是完事的代码:
package arithmetic;

import java.util.Scanner;
public class MyJosephus03 {
/**
* 新建一个节点类,类里有数据域和指针域,
*
* @author 海浪之心
*
*/
static class Node {
int value;
Node next;

// 构造方法用于给数据域初始化
Node(int value) {
this.value = value;
}
}

/**
* 通过循环链表实现
*/
public void test_Node() {

Scanner input = new Scanner(System.in);
System.out.print("请输入总人数:");
int total = input.nextInt();
System.out.print("请输入自杀号码:");
int num = input.nextInt();

Node node = new Node(1); //定义一个头节点,用于形成一个循环列表
Node x = node;

for(int i = 2; i <= total; i++){
x = (x.next = new Node(i)); //建立一个单向链表,将对链表进行
初始化
}
x.next = node; //尾节点指向头节点,形成一个循环的链表

System.out.println("出圈的顺序为:");
//循环的条件为只剩下最后一个人
while(x != x.next){
for(int i = 1; i < num; i++){
x = x.next; //循环完成之后 ,x指向将出列的前一个节点
}
System.out.print(x.next.value + " ");
x.next = x.next.next; //将出殡的人员从链表中清除
}
System.out.println();
System.out.println("存活的人为:"+x.value);

}
public static void main(String[] args) {
MyJosephus03 josephus = new MyJosephus03();
josephus.test_Node();
}

}

相关文档
最新文档