1、福州大学数计学院数据结构上机实验报告专业:应用数学学号 姓名 班级实验名称线性表结构及其应用 实验内容 约瑟夫环问题实验目的和要求实验目的:利用单向循环链表解决约瑟夫环问题,提高综合设计能力。基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各人的编号。问题描述和主要步骤问题描述:约瑟夫问题:编号为 1,2,n 的 n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值 m,从第一个人开始按顺时针方向自 1 开始顺序报数,报到 m 时停止报数。报 m 的人出列,将他的密码作为新的 m 值,从他在顺时针方向上的下一个人开始重新从 1 报数,如此
2、下去,直至所有人全部出列为止。试设计一个程序来求出出列顺序,并输出结果。代码实现:#include#includetypedef struct nodeint number;int pass;struct node *next;Node,*List;/初始化循环单链表void initList(List L)L-number = 0;L-pass = 0;L-next = L;/尾插法建立循环单链表void createFromTail(List head,int num,int pas,int length)int i;Node *pri;Node *tmp;head-number = nu
3、m0;head-pass = pas0;pri = head ;for(i = 1;inumber = numi;tmp-pass = pasi;pri-next = tmp;pri = tmp;pri-next = head;/ 从链表中删除void deleteFromList(List *head,Node *tmp)Node *tmp1;Node *tmp2;tmp1 = *head;tmp2 = tmp1;/如果链表剩了一个元素if(tmp-next = tmp)tmp-number = 0 ;tmp-pass = 0;return;/如果此时删除了头节点,此时将头节点转移到头节点的
4、下一个结点if(*head)-number = tmp-number)Node *x;Node *y;x = (*head)-next;while(x != (*head)y = x;x = x-next;y-next = (*head)-next;*head = (*head)-next;else/找到这个节点,删除他while(tmp1-number != tmp-number)tmp2 = tmp1;tmp1 = tmp1-next;tmp2-next = tmp1-next;/ 约瑟夫计数void yuesefu(List head, int m)Node *tmp;tmp = hea
5、d;int time;time = m-1;int i = 0;printf(“出队的顺序:(初始化的 m=20)n“);while(tmp-number != 0) /链表中此时没有结点,则退出for(i=0;inext;printf(“%d “,tmp-number);time = tmp-pass - 1;deleteFromList(/删除结点tmp = tmp-next;/从下一个结点又开始计算 int main(int argc, char *argv)int i;Node *p;int num7 = 1,2,3,4,5,6,7;int pas7 = 3,1,7,2,4,8,4;List head;head = (List)malloc(sizeof(List);initList(head);createFromTail(head,num,pas,sizeof(num)/sizeof(num0);p = head;printf(“n 约瑟夫计数前,每个数和他的密码:n“);for(i = 0;inumber,p-pass);p = p-next;printf(“n“);yuesefu(head,20);printf(“n“);return 0;实验结果(截图表示)研究与探讨通过这次实验对单链表有了更深的了解,在实验中还存在一些问题,需要多做练习来加强。