数据结构课程设计报告约瑟夫环完整版[1]
约瑟夫环问题 实验报告

return count==0; } template <class T> bool SqList<T>::Full() const { return count==maxsize; } template <class T> int SqList<T>::Length() const { return count; } template <class T> void SqList<T>::Clear() { count=0; //这里并不是将所有元素删除,而是将元素个数置 0,实际上元素还在,但可以重新输入元素替换原来的元素 } template <class T> bool SqList<T>::SetElem(int position,const T &e) { if(position<1||position>Length()) //范围出错 { cout<<"范围出错,无法赋值!"<<endl; return false; } else { elems[position-1]=e; return true; } }
for(;i<=m;i++) { j++; if(j>len) j=1; while(S.GetElem(j)==0) { j++; if(j>len) j=1; } } if(j==0) j=1; cout<<S.GetElem(j)<<" "; S.SetElem(j,0); flag++; i=1; } cout<<endl; } return 0; } 测试用例:
数据结构课程设计 约瑟夫环问题(报告+代码)

学院计算机与信息工程系数据结构课程设计设计题目:约瑟夫环问题专业班级学号姓名指导教师2010年12月20日约瑟夫环一.实验目的:本实验是设计一个可以解决约瑟夫环问题的程序。
此程序要求利用单向循环链表存储结构模拟此过程,按照出列的顺序印出个人的编号。
二.实验环境:VC2008.三.试验步骤:1.问题分析和任务定义本实验要求设计一个程序解决约瑟夫环问题,且要利用单向循环链表存储结构模拟此过程。
这就要求我们必须用链表结构而不能用像数组等其它结构。
首先输入的数据必须是整型且是整数,同样输出的也必须是整型且整数;其次也要备好测试数据(包括合法的输入数据和非法形式输入的数据)以此来检查程序是否符合要求;最后2.数据类型和系统设计链表存储结构的定义:typedef struct Node{}SeqList链表的建立:SeqList * Creat(int num){}链表的输出:void OutQueue(SeqList * tail, int num, int code){}3.详细设计:#include <stdio.h>#include <stdlib.h>typedef struct Node{int num;int code;struct Node * next;}SeqList;SeqList * Creat(int);void OutQueue(SeqList *, int , int );int main(){int n,m,i;printf( " 姓名:徐正杰学号:090502201:\n");printf("Input The Number of People, Frist Code:");{int num = 0,code = 0;scanf("%d%d",&num, &code);{SeqList * tail = NULL;tail=Creat(num);OutQueue(tail, num, code);}}return 0;}SeqList * Creat(int num){getchar();SeqList * tail = NULL;tail=(SeqList *)malloc(sizeof(SeqList));{int i = 1, code = 0;printf("Input Num.%d Code:", i);scanf("%d", &code);tail->num = i;tail->code = code;tail->next = tail;{SeqList * p = NULL;for(i = 2; i <= num; ++i){p = (SeqList *)malloc(sizeof(SeqList));if(p){printf("Input Num.%d Code:", i);scanf("%d", &code);p->num = i;p->code = code;p->next = tail->next;tail->next = p;tail = p;}else{perror("Out of menroy!");getchar();exit(1);}}}}return(tail);}void OutQueue(SeqList * tail, int num, int code) {printf("Out of Queue:");{SeqList * p;while(tail - tail->next){code=(code-1)%num+1;{int i;for(i = 1; i < code; ++i){tail = tail->next;}}p = tail->next;printf("%d,", p->num);tail->next = p->next;code = p->code;free(p);p = NULL;--num;}}printf("%d.",tail->num);free(tail);tail = NULL;}4.调试分析在本次试验调试中很不顺利。
实验报告1约瑟夫环

《数据结构》实验报告班级:姓名:学号:日期:08-10-20题目:约瑟夫环一、上机实验的问题和要求:问题描述:编号为1到n的n个人围成一圈,每人带一个密码c,以m为报数上限。
然后从第一个人开始顺时针自1开始报数,报到m的人出列,将其密码作为新的m值,从他的下一个人开始,同样顺时针自1开始报数,依次循环下去,直到所有的人都出列!要求得到依次出列的那些人的编号序列!基本要求:用C代码实现此活动,要求使用一定的算法进行操作,并最终通过程序运算出最后的结果!二、程序设计的基本思想,原理和算法描述:(包括程序的模块结构,数据结构,输入/输出设计,符号名说明等)基本思想:利用不带头结点单向循环链表模拟该活动,在实现了一切动作之后,运用一定的算法得到最终的结果。
程序的模块结构:定义了相关的结构体之后,主要有以下几大模块:1.建立由头指针指示的有n个结点的不带头结点的单向循环链表crt_CLinkList(H,n);2.寻找、输出、删除H单循环链表的第m个结点locfor(H,m);3.最后通过main函数体处理参数的输入与显示,并调用以上两函数,最终解决问题。
主要数据结构:单链的循环链表,即线性表的链式存储结构。
算法的伪码描述:结构体定义如下:typedef struct Lnode /*定义单链表*/{int number; /*编号*/int cipher; /*密码*/struct Lnode *next; /*指针*/}Lnode,*CLinklist; /*重定向命名*/CLinklist H; /*H为全局单链表*/算法的实现详见源程序。
输入/输出设计本程序并未采用任何二进制文件出入的方式,这点说明将在最后总结提到。
至于函数的出入口问题,在源程序及注释中将得到详细说明,这里不再赘述。
三、源程序及注释:(说明函数功能、入口及出口参数,其他)#include <stdio.h> /* 头文件*/#include <stdlib.h>#include <alloc.h>typedef struct Lnode /*定义单链表*/{int number; /*编号*/int cipher; /*密码*/struct Lnode *next; /*指针*/}Lnode,*CLinklist; /*重定向命名*/CLinklist H; /*H为全局单链表*/struct Lnode *crt_CLinkList(CLinklist H,int m) /*创建一个不带头结点的单向循环链表*/{ /*其中,H为全局单链表,m为链表结点总数*/ int i; /*循环记数用*/struct Lnode *ptr1; /*用于索引*/if((ptr1=(struct Lnode *)malloc(sizeof(struct Lnode)))==NULL) /*一旦动态内存分配失败,报错退出!*/ {perror("malloc");return ptr1;}H=ptr1; /*形成单个结点的单循环链表*/ptr1->next=H;for(i=1;i<m;i++) /*形成m个结点的不带头结点的单循环链表*/ {if((ptr1->next=(struct Lnode *)malloc(sizeof(struct Lnode)))==NULL){perror("malloc");ptr1->next=H;return H;}ptr1=ptr1->next; /*其中H指头,ptr指尾*/ptr1->next=H;}return H; /*返回成功新建的单链表H*/}void locfor(CLinklist H,int m) /*寻找输出删除链表H中的第m个结点*/{ /*H为全局链表,m为要查找删除的结点位置*/ int i; /*循环计数*/struct Lnode *ptr;for(i=1;i<=5;i++) /*考虑图形界面的美观问题*/printf("number\tcipher\t");i=1; /*初始化*/while(H->next!=H) /*只剩单个结点时停止循环,进行最后输出!*/ {if(m==1) /*考虑进行自身删除的情况,即m=1*/{for(ptr=H->next;ptr->next!=H;ptr=ptr->next);/*正因为是自身删除才要费大劲寻找其父结点*/printf("%-6d\t",H->number); /*找到后,先输出*/printf("%-6d\t",H->cipher);m=H->cipher; /*确定下一次寻找的m值*/ptr->next=H->next; *删除结点,即自身结点*/ptr=ptr->next;free(H); /*因为对于链表中的结点,每个之前都分配了内存,所以free是必要的*/H=ptr; /*不同于以下普通结点的删除,自身删除还要还原H*/i=1; /*i重置,以方便下一次的循环操作*/}else if(i==m-1) /*因为从自身开始即为1号,因为m-1,而不是m*/{ptr=H->next; /*结点的删除操作同于上面的情况!*/printf("%-6d\t",ptr->number);printf("%-6d\t",ptr->cipher);m=ptr->cipher;H->next=ptr->next;H=H->next;free(ptr);i=1;}else{H=H->next; /*若未找到,则继续遍历!*/i++;}}printf("%-6d\t",H->number); /*对于单个结点的单循环链表,进行最终的输出操作!*/ printf("%-6d",H->cipher);free(H); /*完成所有任务并释放所有内存占用!*/}void main() /*主函数接口*/{ /*调用所有函数,进行实验模拟,并得出实验结果!*/ int i,j,n=30,m,k;struct Lnode *ptr;randomize(); /*因为下面调用了random函数,故此处的初始化很有必要!*/ printf("Now the experiment will begin.You have two choices!\n");/*数据输入可以电脑随机,也可以自行输入*/printf("If you want to enter the datas all by yourself,please enter 1.\n");/*自行输入(方便检测程序问题)*/ printf("If you want to get the datas by the computer,please enter 0.\n"); /*电脑随机产生数据*/printf("Now your choice:"); /*用户选择*/scanf("%d",&j);while(j!=0&&j!=1) /*考虑程序的完善性,对于误输入的提示并报警!*/ {printf("\nYou enter is unillage!Please try again!\n");printf("Now your choice:"); /*重新输入*/scanf("%d",&j);}H=crt_CLinkList(H,n); /*初始化链表*/if(j==0) /*电脑随机充入数据*/for(i=1;i<=30;i++){H->number=i;H->cipher=rand(); /*随机函数*/H=H->next;}else /*此时选择实验者输入数据!*/{for(i=1;i<=30;i++){H->number=i;printf("Now number %d,please enter the cipher:",i);scanf("%d",&k);H->cipher=k;H=H->next;}}m=rand(); /*默认情况下,m随机产生*/printf("Do you want to enter the number m?Enter 1 to set or others cancel!\n");/*当然,如果想自已输,可以进行覆盖*/scanf("%d",&k);if(k==1) /*自行输入m值*/{printf("Please enter the number m:");scanf("%d",&m);}system("cls"); /*考虑屏幕大小,进行分屏显示*/printf("All followed are your datas!\n"); /*界面友善*/for(i=1;i<=5;i++)printf("number\tcipher\t");for(i=0;i<30;i++) /*显示所有处理前数据*/{printf("%-6d\t",H->number);printf("%-6d\t",H->cipher);H=H->next;}printf("And the number m is :%d\n",m);printf("\nAfter the program,the result is:\n");locfor(H,m); /*对所有数据进行实验处理,直至所有结点处理完!*/ getchar();printf("\nPress any key return!"); /*TC环境下,方便查看结果!*/getchar();}四、用户使用说明与测试运行结果:1.运行程序后,首先弹出界面,截图如右:理性化的选择:如果打1,则所有的cipher均由用户输入,这样方便对特殊数据进行程序测试!如果打0,那么所有的数据均由电脑产生!那如果打其他的呢?考虑到误输入,加了一个循环,以提高程序的健壮性!2.首先自行输入数据进行测试。
约瑟夫环-joseph环-数据结构与算法课程设计报告

合肥学院计算机科学与技术系课程设计报告2009~2010学年第二学期课程数据结构与算法课程设计名称joseph环学生姓名朱玉庭学号0804012029专业班级08计本(2)指导教师王昆仑、张贯虹2010 年06月08号一、问题分析和任务定义:约瑟夫环是一个数学游戏,根据游戏内容的描述,能够很容易的看出,游戏中的玩家顺时针围坐一圈,能够很容易的发现,这跟本课上的单循环链表非常相似,所以可以通过单循环链表存储结构模拟此过程,当游戏中的玩家出列时,可以通过删除单循环链表中的结点来实现。
二、数据结构的选择和概要设计:选择带为指针的单循环链表来解决这个问题,先建立一个空链表,然后根据人数生成具有相应结点的单循环链表,知道密码后,通过循环来找到对应的结点,然后将该结点的编号输出,改变密码,最后删除结点,以此类推,知道编码全部输完,即可得到结果序列。
三、详细设计和编码:本题目是通过单循环链表存储结构来模拟此过程的,首先要先明确该单循环链表中结点的结构类型,定义如下:typedef struct Node{int key; //每个人持有的密码int num; //这个人的编号struct Node *next; //指向下一个结点}Link;当生成单循环链表时,就需要用到课本上创建单循环链表的有关内容了,可以先通过子函数Link *InitList()建立一个空链表,返回指针L,然后将返回的指针代入子函数Link *Creater(Link *L,int n)的形参中,对循环链表进行初始化,并且也返回一个指针,然后再将这个返回的指针代入到输出函数void Output(Link *L,int n,int m)的形参中,要想根据题目要求完成序列的输出,需要通过两个for循环来实现,第一个循环for(i=1;i<=n;i++) ,因为一个用n个人,所以结果要输出n个编号,这个循环每循环一次输出一个编号即printf("%d ",q->num),并将该编号下的密码赋值给m 即m=q->key,当循环完毕时正好将编号全部输出,第二个循环for(j=1;j<m;j++) p=p->next; q=p->next; 用以找到相应的结点,并用指针q指向它,当完成了编号的输出和密码的赋值后,删除q指向的结点,将两个循环适当结合,即可输出正确的结果序列,其中的人数n和初始密码在主函数中确定。
数据结构约瑟夫环实验报告

《数据结构与算法设计》约瑟夫环实验报告——实验一专业:物联网工程班级:物联网1班学号:15180118姓名:刘沛航一、实验目的1、熟悉VC环境,学习使用C语言利用链表的存储结构解决实际的问题。
2、在编程、上机调试的过程中,加深对线性链表这种数据结构的基本概念理解。
3、锻炼较强的思维和动手能力和更加了解编程思想和编程技巧。
二、实验内容1、采用单向环表实现约瑟夫环。
请按以下要求编程实现:①从键盘输入整数m,通过create函数生成一个具有m个结点的单向环表。
环表中的结点编号依次为1,2,……,m。
②从键盘输入整数s(1<=s<=m)和n,从环表的第s个结点开始计数为1,当计数到第n个结点时,输出该第n结点对应的编号,将该结点从环表中消除,从输出结点的下一个结点开始重新计数到n,这样,不断进行计数,不断进行输出,直到输出了这个环表的全部结点为止。
例如,m=10,s=3,n=4。
则输出序列为:6,10,4,9,5,2,1,3,8,7。
三、程序设计1、概要设计为了解决约瑟夫环的问题,我们可以建立单向环表来存储每个人的信息(该人的编号以及其下一个人的编号),及结点,人后通过查找每个结点,完成相应的操作来解决约瑟夫问题。
(1) 抽象数据类型定义ADT Joh{数据对象:D={|,1,2,,,0}i i a a ElemSet i n n ∈=≥K数据关系:R1=11{,|,,1,2,,}i i i i a a a a D i n --<>∈=K基本操作:create(&J, n)操作结果:构造一个有n 个结点的单向环表J 。
show(J)初始条件:单向环表J 已存在。
操作结果:按顺序在屏幕上输出J 的数据元素。
calculate( J,s,n)初始条件:单向环表J 已存在,s>0,n>0,s<环表结点数。
操作结果:返回约瑟夫环的计算结果。
}ADT Joh(2)宏定义#define NULL 0#define OK 1#define ERROR -1(3)主程序流程(4)程序分为下述模块:1)主函数模块——执行输入调用其他的功能函数2)创建环表模块——创建单向环表3)计算处理模块——计算出要出列的标号并输出4)显示模块——输出建立好的环表调用关系如下:2、详细设计(1)数据类型设计typedef int ElemType; //元素类型typedef struct {ElemType data;struct Joh *next;}Joh, *LinkList,*p; //结点类型,指针类型(2)操作算法Status create(LinkList &J,int n){//创建一个有n个结点的单向环表if(n<=0)return ERROR; //n<0错误J=(LinkList)malloc(sizeof(J));J->data=1;J->next=J;//建立第一个结点for(int i=n;i>1;--i){p=(LinkList)malloc(sizeof(J));p->data=i;p->next=J->next;J->next=p;//插入到表头}return OK;}//createvoid show(LinkList J){//主要的操作函数//顺序输出环表J的结点p=J;printf("%d ",p->data);p=p->next;while(p!=J){ //循环终止条件printf("%d ",p->data);p=p->next;}}//showvoid calculate(LinkList J,int s,int n){p=J;Joh *head=p; //声明结点while(p->data!=s){p=p->next;head=p;}//寻找起始结点while(p->next!=p){ //终止条件for(int i=0;i<n-1;i++){head=p; //保存前置节点p=p->next;}printf("%d ",p->data);head->next=p->next; //删除已输出结点p=head->next;}if(n!=1)printf("%d\n",p->data);elseprintf("\n");}//calculate(3)主函数代码int main(){//主函数Joh *J;int m,s,n;printf("The num of node is:");scanf("%d",&m);create(J,m); //创建单向环表Jshow(J); //输出J的数据printf("\n");printf("The first node which you want is:");scanf("%d",&s);printf("The internal which you want is:");scanf("%d",&n);calculate(J,s,n); //计算并输出结果return 0;}//main四、程序调试分析1、细节决定成败,编程最需要的是严谨,如何的严谨都不过分,往往检查了半天发现错误发生在某个括号,分号,引号,或者数据类型上。
数据结构实验一 约瑟夫环问题实验报告电子版

for(i = 1;i<length;i++){
tmp = (Node *)malloc(sizeof(Node));
tmp->number = num[i];
tmp->pass = pas[i];
pri->next = tmp;
pri = tmp;
pri->next = head;
for(i=0;i<time;i++){ //找到要删除的结点
tmp = tmp->next;
}
printf("%d ",tmp->number);
timeห้องสมุดไป่ตู้= tmp->pass - 1;
deleteFromList(&head,tmp);//删除结点
tmp = tmp->next;//从下一个结点又开始计算
initList(head);
createFromTail(head,num,pas,sizeof(num)/sizeof(num[0]));
p = head;
printf("\n约瑟夫计数前,每个数和他的密码:\n");
for(i = 0;i<sizeof(num)/sizeof(num[0]);i++){
}
}
// 从链表中删除
void deleteFromList(List *head,Node *tmp)
{
Node *tmp1;
Node *tmp2;
tmp1 = *head;
tmp2 = tmp1;
//如果链表剩了一个元素
约瑟夫环-课程设计

目录1题目 (1)1.1问题描述 (1)1.2功能要求 (1)2算法思想描述: (1)2.1算法概述: (1)2.2算法具体分析 (2)3 程序结构 (3)3.1主函数流程图 (3)3.2 josephus()函数流程图 (4)4 实验结果与分析 (5)4.1实验测试中的关键代码与各模块测试结果的分析与说明 (5)4.2试验过程中所遇到的问题分析与解决 (11)5课程设计总结 (12)参考文献 (13)1题目约瑟夫环1.1问题描述编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
1.2功能要求A利用单循环链表作为存储结构模拟此过程;B键盘输入总人数、初始报数上限值m及各人密码;C按照出列顺序输出各人的编号。
2算法思想描述:2.1算法概述:建立一个循环单链表,然后输入要建立结点的个数,在每个结点输入一个密码,同时按输入时的顺序进行编号:1,2,3,4, ……n.任选一个正整数x作为初始报数上限值.从定义的那个头结点开始,数到x,输出该结点所储存的编号和密码.并将该密码作为新的x值,同时还将该密码所在的结点删除.如此循环链表还剩最后一个数据的时候停止此循环.再将最后一个没在循环里面的编号和密码另外输出.循环链表如图1所示:图22.2算法具体分析(1)window(),switch(),upbar(), downbar(),key()这几个函数是构建本程序菜单所必须的函数.window()用于开窗口,以坐标的形式开辟一个窗口,并且可以在窗口里面储存数据.switch()创建菜单选项,key()主要用于获取键盘上的字符(包括字母和方向键,enter键),upbar()和 downbar()实现光条的上移和下移. textbackground(),textcolor()。
约瑟夫环课程设计报告

课程设计报告课程设计名称:数据结构课程设计课程设计题目:约瑟夫环院(系):专业:班级:学号:姓名:指导教师:目录1 课程设计介绍 (1)1.1课程设计内容 (1)1.2课程设计要求 (1)2 课程设计原理 (2)2.1课设题目粗略分析 (2)2.2原理图介绍 (2)2.2.1 功能模块图(如图2.1) (2)2.2.2 流程图分析 (3)3 数据结构分析 (5)3.1存储结构 (5)3.2算法描述 (5)4 调试与分析 (6)4.1调试过程 (6)4.2程序执行过程 (6)参考文献 (8)附录(关键部分程序清单) (9)1 课程设计介绍1.1 课程设计内容编号为1,2,……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
使用单循环链表作为存储结构分析:由题意可以将每个人看做链表上的一个节点,每个人持有的密码即为每个节点所存储的数据;相邻的人之间存在连结关系,即链表的两个相邻节点之间由指针来进行关联;最后一个人和第一个人也存在连结关系,即链表的末尾节点和头结点相连构成了单循环链表存储结构。
执行报数过程可以看做一个单独指针依次指向每一个节点,有人出列即删除掉链表中相应的节点。
1.2 课程设计要求1.参考相应的资料,独立完成课程设计任务。
2.交规范课程设计报告和软件代码。
2课程设计原理2.1 课设题目粗略分析根据课设题目要求,程序应该分为两大部分:1、单循环链表储存结构的建立:建立所需的单循环链表数据存储结构,对每个节点输入所需的密码、序号数据并通过指针连接成单循环链表。
2、实现约瑟夫环数据出列顺序的算法:依照题目要求按照报数上限对节点进行查找和删除操作,按顺序输出出列的节点序号,依照每次出列的节点存储的密码修改报数上限循环操作直到全部节点出列完毕程序运行结束。
(完整word版)约瑟夫环课程设计实验报告

《数据结构》课程设计报告课程名称:《数据结构》课程设计课程设计题目:joseph环姓名:院系:计算机学院专业:年级:学号:指导教师:2011年12月18日目录1 课程设计的目的 (2)2 需求分析 (2)3 课程设计报告内容 (3)1、概要设计 (3)2、详细设计 (3)3、调试分析 (x)4、用户手册 (x)5、测试结果 (6)6、程序清单 (7)4 小结 (10)1、课程设计的目的(1)熟练使用C++编写程序,解决实际问题;(2)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;(3)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;(4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力;2、需求分析1、问题描述:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
设计一个程序来求出出列顺序。
2、要求:利用不带表头结点的单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。
3、测试数据:m的初值为20,n=7 ,7个人的密码依次为3,1,7,2,4,7,4,首先m=6,则正确的输出是什么?输出形式:建立一个输出函数,将正确的输出序列3、课程设计报告内容概要设计:在理解了题目后,我先想到的是我们所学的单链表,利用单链表先建立循环链表进行存贮,建立完循环链表后,我将所要编写的函数分为了两块,一块是经过学过的单链表改编的循环链表的基本操作函数,还有一块是运行约瑟夫环的函数。
详细设计:我先建立一个结构体,与单链表一样,只是多了一个存密码的code域struct LinkNode{int data; //顺序int code; //密码LinkNode *next;};建立一个类LinkList ,包含的函数:LinkList(); //构造函数void Creat(const int ); //创建循环链表int Delete(LinkNode* ); //删除报到数的结点int Joseph(int ); // 约瑟夫环私有成员是LinkNode* head; //指向第一个结点的指针LinkNode* elem; // 同上int len; //长度我定义了一个elem指针是为了约瑟夫环里运行方便,elem只在约瑟夫环这个函数里用到,其他函数没有特别大的用处。
数据结构 约瑟夫环课程设计报告

课程设计报告一、需求分析1、本演示程序中,利用单向循环链表存储结构模拟约瑟夫问题的进行。
程序运行后,首先要求用户指定初始报数上限值,然后读取个人的密码。
可设n≤30。
此题所用的循环链表中不需要“头结点”,因此在程序设计中应注意空表和非空表的界限。
2、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令:相应的输入数据和运算结果显示在其后。
3、程序执行的命令包括:1)构造约瑟夫环;2)执行约瑟夫环,并输出出列人的序号以及相应的密码;3)结束。
4、测试数据1)m的初始值为20;2)n=7,7个人的密码依次为:3、1、7、2、4、8、4。
3)首先m值为6,正确的出列顺序应为6、1、4、7、2、3、5。
二、概要设计为实现上述程序功能,应以单向循环链表表示约瑟夫环。
为此,需要两个抽象数据类型:单向循环链表和约瑟夫环。
1)、单向循环链表的抽象数据类型定义为:ADT List{数据对象:D={ai|ai∈Elemset,i=1,2,…,n,n≥0}数据关系:R1={<a(i-1),ai>|a(i-1),ai∈D,i=2,…n}基本操作:InitList(&L)操作结果:构造一个空的链表L。
DestroyList(&L)初始条件:线性表L已存在。
操作结果:销毁线性表L。
ListLength(L)初始条件:线性表L已存在。
操作结果:返回L中数据元素个数。
GetElem(L,i,&e)初始条件:线性表L已存在,1≤i≤ListLength(L)。
操作结果:用e返回L中第i个数据元素的值。
ListInsert(&L,I,e)初始条件:线性表L已存在,1≤i≤ListLength(L)+1。
操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1。
ListDelete(&L,i,&e)初始条件:线性表L已存在且非空,1≤i≤ListLength(L)。
数据结构joseph课程设计

数据结构joseph课程设计一、课程目标知识目标:1. 学生能理解约瑟夫问题(Josephus problem)的背景和数学原理,掌握其与数据结构中循环链表的关系。
2. 学生能够掌握循环链表的基本操作,包括节点的插入、删除以及遍历。
3. 学生能够运用所学的循环链表知识解决约瑟夫问题,并理解其算法的效率。
技能目标:1. 学生能够运用编程语言(如C/C++/Java等)实现循环链表,并完成相应的约瑟夫问题求解程序。
2. 学生通过实际操作循环链表,提高逻辑思维能力和编程实践能力。
3. 学生能够通过分析、讨论和解决问题,培养团队协作能力和问题解决能力。
情感态度价值观目标:1. 学生通过解决实际问题,增强对数据结构学习的兴趣和热情,形成积极向上的学习态度。
2. 学生在团队协作中学会尊重他人,培养良好的沟通能力和合作精神。
3. 学生通过探究和解决约瑟夫问题,体会数学和计算机科学的实际应用价值,增强对科学的敬畏之心。
课程性质:本课程设计属于数据结构学科范畴,以实践操作和问题解决为核心,强调理论与实践相结合。
学生特点:考虑到学生已具备一定的编程基础和逻辑思维能力,课程设计将注重培养学生的实践能力、团队协作能力以及创新意识。
教学要求:教师应关注学生的个体差异,因材施教,引导学生通过自主探究、合作学习等方式达到课程目标。
在教学过程中,注重过程评价和结果评价相结合,全面评估学生的学习成果。
二、教学内容本节教学内容围绕数据结构中的循环链表及其应用——约瑟夫问题展开,具体安排如下:1. 循环链表基础知识回顾:- 循环链表的定义与特点- 循环链表的节点结构- 循环链表与普通链表的区别2. 循环链表的操作:- 节点的插入与删除- 循环链表的遍历- 循环链表的应用场景3. 约瑟夫问题介绍:- 约瑟夫问题的背景和数学原理- 约瑟夫问题与循环链表的关系4. 约瑟夫问题求解:- 算法设计思路- 编程实现步骤- 算法效率分析5. 实践环节:- 编写循环链表的基本操作函数- 编写求解约瑟夫问题的程序- 调试与优化程序6. 教学案例分析:- 结合实际案例,讲解循环链表在解决约瑟夫问题中的应用- 分析案例中的算法优化方法教学内容根据课本相应章节进行组织,确保学生能够在掌握循环链表基础知识的基础上,学会解决实际问题。
数据结构实验报告约瑟夫环

数据结构实验报告约瑟夫环约瑟夫环是一个经典的问题,涉及到数据结构中的循环链表。
在本次数据结构实验中,我们将学习如何使用循环链表来解决约瑟夫环问题。
约瑟夫环问题最早出现在古代,传说中的犹太历史学家约瑟夫斯·弗拉维奥(Josephus Flavius)在围攻耶路撒冷时,为了避免被罗马人俘虏,与其他39名犹太人躲进一个洞穴中。
他们决定宁愿自杀,也不愿被敌人俘虏。
于是,他们排成一个圆圈,从第一个人开始,每次数到第七个人,就将他杀死。
最后剩下的人将获得自由。
在这个问题中,我们需要实现一个循环链表,其中每个节点表示一个人。
我们可以使用一个整数来表示每个人的编号。
首先,我们需要创建一个循环链表,并将所有人的编号依次添加到链表中。
接下来,我们需要使用一个循环来模拟每次数到第七个人的过程。
我们可以使用一个指针来指向当前节点,然后将指针移动到下一个节点,直到数到第七个人为止。
一旦数到第七个人,我们就将该节点从链表中删除,并记录下该节点的编号。
然后,我们继续从下一个节点开始数数,直到只剩下一个节点为止。
在实现这个算法时,我们可以使用一个循环链表的数据结构来表示约瑟夫环。
循环链表是一种特殊的链表,其中最后一个节点的指针指向第一个节点。
这样,我们就可以实现循环遍历链表的功能。
在实验中,我们可以使用C语言来实现循环链表和约瑟夫环算法。
首先,我们需要定义一个节点结构体,其中包含一个整数字段用于存储编号,以及一个指针字段用于指向下一个节点。
然后,我们可以实现创建链表、添加节点、删除节点等基本操作。
接下来,我们可以编写一个函数来实现约瑟夫环算法。
该函数接受两个参数,分别是参与游戏的人数和每次数到第几个人。
在函数内部,我们可以创建一个循环链表,并将所有人的编号添加到链表中。
然后,我们可以使用一个循环来模拟每次数到第几个人的过程,直到只剩下一个节点为止。
在每次数到第几个人时,我们可以删除该节点,并记录下其编号。
最后,我们可以返回最后剩下的节点的编号。
数据结构课程设计报告(约瑟夫问题)

数据结构课程设计报告(约瑟夫问题)问题描述约瑟夫问题:编号为1-n的n个人围坐圆桌旁,从任一指定编号为k的人开始报数,报数为m的人离开圆桌,下一个人接着从n开始报数, 报数为m的人又离开圆桌,依此重复,直至所有人离开圆桌.编一程序,输出离开圆桌的人的编号序列.设计思想首先采单循环链表建立整个约瑟夫环,手动输入总人数(既链表的长度)、每个人的所持下一轮报数出对值和初始报数值。
node->num为人的编号,node->为此人所持的下一轮报数值。
建立单循环链表后,通过初始报数值找到出列的人,输出node->num的值,然后将该结点中的data值作为下一轮的报数值。
重复以上过程直至所有的人都出列,则程序结束。
主要算法do{k=1;while(k!=m)//当k=m时,结束第一轮报数{p1=p1->next;k++;}//报数中将指针指向下一位p2=p1->next;p1->next=p2->next;//把报数为m的人的结点从链表中删除printf("编号为%d的人出列,他的key%d作为新的m值/n",p2->num,p2->data);//m=p2->data;//报数为m的人的密码作为下一轮新的m值free(p2);//释放报m的人的结点}while(p1->next!=p1);//当p1->指向自己时,报数结束的值加一,当k=m时,此时p1指向人出列,p2指向该结点的上一结点,k为计数器,指针每移动一次,k让上一结点的next指向该结点的下一结点,然后删除该结点。
P1指向该结点下一结点,令k=1,再开始下一轮报数。
等到所有人出列后,循环结束。
for(i=1;i<=n;i++){printf("请输入%d号同学的key",i);scanf("%d",&j);//输入学生所带有的密码p1->next =(listnode*)malloc(sizeof(listnode));//建立一个空间p1=p1->next ;p1->data=j;p1->num=i;//对结点的num和data成员赋值p1->next=head->next; }定义指针p1,然后建立一个新结点并将p1->next指向他,再将地址赋给p1,最后将head->next赋给p1->next,构成了循环单链表,然后让所有人键入链表并给num和data成员赋值。
数据结构课程设计报告-约瑟夫环问题

华北科技学院课程设计说明书班级: 姓名:____设计题目: 约瑟夫环设计时间:____2011-2-28 至__2011-3-11指导教师:评语:_________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ 评阅成绩:____评阅教师:_____一、设计题目与要求设计题目:约瑟夫环问题描述:编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
基本要求:1、利用单循环链表作为存储结构模拟此过程;2、键盘输入总人数、初始报数上限值m及各人密码;3、显示游戏中队形及各人密码变化过程;4、按照出列顺序输出各人的编号。
二、概要设计实验设计思路:1.以无头结点的单循环链表为存储结构模拟此过程。
2.键盘录入各各同学所持密码,存储在一维数组a[]中。
3.单循环链表初始化时,将密码和编号存入结构体中。
4.进行单链表删除操作,直到链表为空,输出的编号存入数组b[]中5.依次输出b[]中的元素。
程序结构:本程序是单文件程序,构成的函数有LinkedList LinkedListInit(int n,int a[]) 初始化循环单链表void LinkedListTraverse(LinkedList L) 遍历单链表void Play(LinkedList L,int m,int b[],int n) 单循环链表的删除void main() 主函数,输出出队序列其中,void Play()是最主要的函数,初始化单链表后,开始执行该函数,指针按给定的密码值m依次后移m次删除定位后的结点,输出编号,同时获得新的m 值,继续循环,直到该链表为空。
数字结构实验约瑟夫环的实验报告

约瑟夫环一、目的(本次实验所涉及并要求掌握的知识点)熟练掌握线性表的基本操作在两种储存结构上的实现,其中以各种链表的操作和应用作为重点内容。
二、实验内容与设计思想(设计思路、主要数据结构、主要代码结构、主要代码段分析、电路图)1.问题描述:约瑟夫问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
2.基本要求:利用单向循环链表储存结构模拟此过程,按照出列的顺序印出各人的编号。
3.要求:程序运行后,首先要求用户指定出事报数上限值,然后读取各人的密码。
可设n ≦30。
此题所用的循环链表中不需要“头结点”,请注意空表和非空表的界限。
三、实验使用环境(本次实验所使用的平台及软件)本次实验在VC++6.0环境下调试。
四、程序源代码#include<stdio.h>#include<stdlib.h>typedef struct node{int num; //结点的编号int cipher; //密码struct node *next;}linklist;typedef linklist *head; //链表void main(){int n,m,i,j,k;linklist *head=(linklist*)malloc(sizeof(linklist));//开辟一个空间,并将它的起始地址赋给头指针head//linklist *p1,*p2;printf("请输入队列人数");scanf("%d",&n);//输入总人数//printf("请输入初始报数值:");scanf("%d",&m);//输入初始报数值//p1=head;//将头指针head所指地址赋给p1//for(i=1;i<=n;i++){printf("请输入第%d个人的密码:\n",i);scanf("%d",&j);//输入学生所带密码//p1->next=(linklist*)malloc(sizeof(linklist));//建立一个新的空间,并将它的地址赋给p1->next//p1=p1->next;p1->cipher=j;p1->num=i;//对结点的cipher和num成员赋值//p1->next=head->next;//构成单循环链表//}do{k=1;while(k!=m)//当k==m时一轮报数结束//{p1=p1->next;k++;}//报数过程中将指针p1指向下一位//p2=p1->next;p1->next=p2->next;//将报数为m的人得结点从链表中删去//printf("编号为%d的人出列,他的密码%d作为新的m值\n",p2->num,p2->cipher);//报数为m的人出列//m=p2->cipher;//将报数为m的人的密码作为新的m值//free(p2);//释放报m的人的结点//}while(p1->next!=p1);//当p1->next指向的地址是它自己的地址,所有报数结束//printf("编号为%d的人出列,至此所有人出列完毕\n",p1->num);//所有人出列//free(p1);//释放最后一个人的结点//free(head);//释放头结点//printf("程序结束\n");}五、实验结果测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5。
计算机数据结构课程设计报告

数据结构课程设计报告题目一:约瑟夫环题目二:停车场管理题目一:约瑟夫环一、问题描述:约瑟夫问题的一种描述是:编号为1,2···,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将它的密码作为新的m值,从它的顺时针方向的下一个人开始重新从1报数,如此下去,直至全部人出列为止。
最后按照出列的顺序印出各人的编号。
二、数据结构:其主要的数据类型为无头结点的单向循环链表,如下:typedef struct Node{int data; //存储人数int password; //存储的每人所对应的密码struct Node *next;}Node, *LinkList;三、大致的程序流程:1. 函数之间的调用关系图:PersonNumber FirstValue CreatLinkList InitLinkList OutputOrder printResultPassword2.主要模块的流程图:··3.主程序A)以下两个函数作用是构建并初始化一个单循环链表,初始化时将链表*L 赋值给链表*q,(*q)为头指针,并赋值p->data为第一人的编号,赋值p ->password为此人对应的密码。
再通过for()循环,以链表q为过渡,依次给p->next赋值q。
最后令p—>next等于链表L的头指针(*L)。
void CreatLinkList(LinkList *L){/*构建单链表*/(*L) = (LinkList)malloc(sizeof(Node));if ((*L) == NULL){printf("memory allocation failed");exit(1);}}void InitLinkList(LinkList *L, int personNumber){/*初始化单链表*/Node *p, *q;int i ;p = (*L);p->data = 1;p->password = Password();for (i = 2; i <= personNumber; i++){q = (LinkList)malloc(sizeof(Node));if (q == NULL){printf("memory allocation failed");exit(1);}q->password = Password();q->data = i;p->next = q;p = q;}p->next = (*L);}B)以下三个函数的作用分别是确定输入人数,确定每人密码,确定开始的上限制。
数据结构实验报告一-约瑟夫环问题

实验1约瑟夫环问题1.需求分析(1)输入的形式和输入值的范围:每一次输入的值为两个正整数,中间用逗号隔开。
若分别设为n,m,则输入格式为:“n,m”。
不对非法输入做处理,即假设输入都是合法的。
(2)输出的形式:输出格式1:在字符界面上输出这n个数的输出序列输出格式2:将这n个数的输出序列写入到文件中(3)程序所能达到的功能:对于输入的约瑟夫环长度n和间隔m,输出约瑟夫环的出列顺序。
(4)测试数据:包括正确的输入及其输出结果和含有错误的输入及其输出结果。
正确:输入:10,3输出:3 6 9 2 7 1 8 5 10 4输入:41,3输出:3 6 9 12 15 18 21 24 27 30 33 36 39 1 5 10 14 19 23 28 32 37 41 7 13 20 2634 40 8 17 29 38 11 25 2 22 4 35 16 31错误:输入:10 3输出:6 8 7 1 3 4 2 9 5 102.概要设计(1)抽象数据类型的定义:为实现上述程序的功能,可以用整数存储用户的输入。
并将用户输入的值存储于线性表中。
线性表ADT定义如下:ADT list数据对象:整形数据关系:线性关系,即<ai,ai+1>(0≤a<n)。
基本操作:bool remove(int &elem)//移除一个元素,被移除的元素赋给elem//如果操作成功,返回true,否则返回falsebool isEmpty()//判断数组的元素是否清空,空返回true,否则返回falsebool setPos(int place)//设置当前元素的位置,设置成功返回true,否则返回falseint getLength()//获取数组的实际长度(2)算法的基本思想:约瑟夫环问题中的数据是人所在的位置,而这种数据是存在“第一元素、最后元素”,并且存在“唯一的前驱和后继的”,符合线性表的特点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计报告约瑟夫环完整版[1]*******************实践教学*******************兰州理工大学软件职业技术学院2011年春季学期算法与数据结构课程设计题目:约瑟夫环专业班级:姓名:学号:指导教师:成绩:摘要约瑟夫环问题是典型的线性表的应用实例,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。
对于前者要求建立起数据一致性和完整性强、数据安全性好的库。
而对于后者则要求应用程序功能完备,易使用等特点。
经过分析,我们使用MICROSOFT公司的Microsoft Visual C++6.0开发工具,利用其提供的各种面向对象的开发工具,尤其是数据窗口这一能方便而简洁操纵数据库的智能化对象,首先在短时间内建立系统应用原型,然后,对初始原型系统进行需求迭代,不断修正和改进,直到形成用户满意的可行系统。
关键词:单循环链表;c语言;约瑟夫环;目录摘要 (1)序言............................................................................. 错误!未定义书签。
目录. (2)正文 (1)一、问题描述 (1)二、逻辑设计 (2)三、详细设计 (4)四、程序代码 (10)五、程序调试与测试 (10)设计总结 (16)参考文献 (17)致谢 (18)附录 (19)正文一、问题描述约瑟夫环问题描述的是:设编号为1,2,…,n 的n (n>0)个人按顺时针方向围坐一圈,每个人持有一正整数密码。
开始时选择一个正整数作为报数上限m ,从第一个人开始顺时针方向自1起顺序报数,报到m 时停止报数,报m 的人出圈,将他的密码作为新的m 值,从他在顺时针方向上的下一个人起重新从1报数。
如此下去,直到所有人都出圈为止。
令n 最大值为100。
要求设计一个程序模拟此过程,求出出圈的编号序列。
如下图分析: 12 3 4 56 7 8 90 这是第一个人,他的密码是“1”,个他输一个m 值,如果m=3,则从他开始向下走3个 这就是第二步的位置,这时他的密码作为新的m 值,即m=4,同时得到的第一个密码为4;4号出去向下走4,到9这儿;(这这一步完了剩余的为:1,2,3,5,6,,7,8,9,0,) 这就是第三步的位置,这时他的密码作为新的m 值,即m=9,同时得到的第二个密码为9;9号出去向下走9,到0这儿;继续走就行了(这儿剩余的就是:1,2,3,5,6,7,8,0)图1约瑟二、逻辑设计1、循环链表抽象数据类型定义typedef struct LNode//定义单循环链表中节点的结构{int num;//编号int pwd;//password struct LNode *next;//指向下一结点的指针 }LNode;2、本程序包含一下几个模块(1)构造结点模块LNode *createNode(int m_num,int m_pwd) 3 2 7 1 4 8 4 约瑟夫环原理演示图1 2 3 4 5 6 7 第二部:第一次停下的位置,此时6号出列,并将他的值作为新的m 值,即:新的m=8;从7好开始继续向下走8次,到1号的位置最后排序后的密码序列:(本图只演示前两步) 8第三步:第二次,1号出列 第四步:第三次,4号出列 3 第一步:给第一个人赋初始密码为:20则从它开始向下走20次,到6号位置 2 4 1 7 4 6 1 4 7 23 5 图 2 约瑟夫{LNode *p;p=(LNode *)malloc(sizeof(LNode));//生成一个结点p->num=m_num;//把实参赋给相应的数据域p->pwd=m_pwd;p->next=NULL;//指针域为空return p;}(2)创建链表模块void createList(LNode *ppHead,int n)(3)出队处理模块void jose(LNode *ppHead,int m_pwd)(4)约瑟夫环说明输出模块void instruction()(5)菜单模块void menu()(6)主函数模块int main()函数的调用关系图如下:三、详细设计1. 主函数 Case 2:建立的约瑟夫环,并输出输出该约瑟夫环的每个人的出列图3 约瑟夫环函菜单函数; 主函数调用函Case 1:一个简单的输出函数,Case根据流程图,主函数程序如下:int main(){int n,m,x;LNode *ppHead=NULL; menu(); for(;;){printf("\n 请选择要执行的操作:"); scanf("%d",&x); system("cls"); switch(x){ case 1:printf("****************************************************************\n");Main(Menu()功功能1:约瑟夫环说功能2:按要求功能3:退出系输入总输入开始输入每个玩调用:createList(&pp 选择程序运行完,自图 4 主函数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;}2.链表的创建/*创建单向循环链表ppHead ,人数个数为n ,并输入每个人的密码值,若建立失败则生成头结点,让cur 指向他,若建立成功则插入结点P ,cur 指向的数据元素为p,后续为"空"的节点,再把P 插入循环链表ppHead 中*/ 根据流程图,创建链表函数程序如下:void createList(LNode **ppHead,int n) {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)//如果头结点为空 {否 是 createL 从主函数中获取玩如果创建循环单链表,退创建链表完成返回创建储存玩家密码Main(图 5 创建链表函*ppHead=cur=p;//生成头结点,让cur指向他cur->next=*ppHead;//cur的指针域指向自身}else//如果不为空,则插入结点{p->next = cur->next;cur->next = p;cur= p;//cur指向新插入结点}}printf("完成创建!\n"); //提示链表创建完成}3.出队处理Main(从循环链表中按初始密输出其持有的密码移动浮标指针输出密码后,删除相应的结点,执行完后返回jose();出队处理图 6 出队函数/*p指向要删除节点的前一个节点,ppHead指向要删除的节点,使p=ppHead,ppHead再指向要删除节点的下一个节点,使p和ppHead链接,输出p指向节点的编号和密码值,释放ppHead,如此循环,直至把所有节点都打印和删除为止!*/根据流程图,出队函数程序如下:void jose(LNode *ppHead,int m_pwd){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->pwdfree(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);//释放头结点}4. 约瑟夫环说明模块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;}5. 菜单模块void menu(){printf("**************************约瑟夫环*****************************\n");printf("\n");printf(" [1]约瑟夫环问题的阐述\n");printf(" [2]按要求求解约瑟夫环\n");printf(" [0]退出\n");printf("************************** 欢迎使用!****************************\n");}四、程序代码见附录源程序。