约瑟夫环C语言的实现验证报告.docx
《约瑟夫环C语言的实现验证报告.docx》由会员分享,可在线阅读,更多相关《约瑟夫环C语言的实现验证报告.docx(6页珍藏版)》请在冰豆网上搜索。
约瑟夫环C语言的实现验证报告
约瑟夫环
姓名
学号
系别信息与电子系
班级计算
填写日期2010年10月30
一.问题描述
约瑟夫(Joseph)问题的一种描述是:
编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
二.基本要求
利用利用顺序表存储结构及单向循环链表存储结构模拟约瑟夫环,按照出列的顺序印出各人的编号
三.测试数据
m的上限为20,初值为6;
(1)对于n=7,7个人的密码依次为:
3,1,7,2,4,8,4进行测试。
(2)对于从键盘输入的n和n个人的密码进行测试。
4.用数组实现约瑟夫环
程序代码:
#include
voidmain()
{
intnum[100];
intm,n,i,k=0,s=0;
int*p=num;
printf("输入初始密码和人数n\n");
scanf("%d%d",&m,&n);
printf("个人密码\n");
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
i=1;
while(s<=(n-1))//当未退出人数(s)大于等于一时执行循环体
{
if(*(p+i)!
=0)
k++;
if(k==m)
{
printf("%d",i);
m=*(p+i);
*(p+i)=0;//对退出的人编号置零
k=0;
s++;
}
i++;
if(i==(n+1))//当循环到最后一位时返回到第一位
i=1;
}
}
测试数据结果:
五.用链表实现约瑟夫环
程序代码:
#include
#include
typedefstructlist
{
intnum;
intpassward;
structlist*next;
}node;
node*creatlist(intn)
{
node*p,*q,*head;
inti=1;
head=(node*)malloc(sizeof(node));
head->num=i;
printf("请输入第1个密码:
");
scanf("%d",&head->passward);
p=head;
for(i=2;i<=n;i++)
{
q=(node*)malloc(sizeof(node));
if(q==0)return0;
printf("请输入第%d个人的密码:
",i);
scanf("%d",&q->passward);
q->num=i;
p->next=q;
p=q;
}
p->next=head;
returnhead;
}
voidjosephus(node*l,intk)
{
inti;
node*p=l,*q,*s;
while(p->next!
=p)
{
for(i=1;i{
q=p;
p=p->next;
}
printf("%d",p->num);
k=p->passward;
s=p;
q->next=p->next;
p=p->next;
free(s);
}
printf("%d",p->num);
printf("\n");
}
voidmain()
{
node*l;
intn,k;
printf("请输入实验人数:
");
scanf("%d",&n);
printf("请输入初始key的值:
");
scanf("%d",&k);
l=creatlist(n);
josephus(l,k);
}
测试数据结果:
六:
学习体会和实验中遇到的问题
约瑟夫环,经过理解,可以认为是一个数学应用题:
已知n个人围坐在一张圆桌周围。
从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
用数组实现约瑟夫环的过程中,我第一个遇到的问题是理解了实验问题,但算法无法写成表达式,怎样让数组中的元素重复剔除,后来通过网络上的学习和同学的参考理解了。
在数组的实现过程中,我感觉最难的是循环的剔除。
用链表实现过程中,我觉得通过指针的操作比较麻烦,但总体思路比较好操作。
在这次学习中,我觉得数组和指针的应用比较广泛,链表代替数组来实现一些问题我还不熟练,要更多的学习和练习。
广东陶粒,广东陶粒厂2Wr32Oud3Lam