《数据结构》实验报告
题目:求解JOSEPHUS问题
1、程序功能:
解决约瑟夫问题。约瑟夫问题可描述如下:设有n个人围成一个环,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人开始数,数到第m的人又出列,如此重复,直至所有人都出列为止。求这些人出列的顺序。
2、数据结构描述:
向量法数据结构。定义了一个数组,每个元素代表一个人,元素的数值代表人的序号。当数到最后一个元素时,转到第一个元素继续数,以此模拟一个环。
循环链表法数据结构。定义了一个循环链表,每个结点包括一个序号和一个指针。每个结点代表一个人,序号代表人的序号。头指针指示第一个结点,即第一个人。
3、程序结构描述:
1) 构造一个数组或循环链表,并输出。
2) 查找起始元素,并顺延m。找到需要被删除的元素,并输出。
3) 删除需要被删除的元素,并将后面的元素提前一位。
4、算法描述:
向量法。构造好数组后,找到第s个元素,即A[s-1]。然后循环,每次s+1,直至顺延到第s+m-1个元素A[s+m-2],即需要被删除的数。若s+m-1超出数组长度,则在数到最后一个元素时需从第一个元素继续数,以此类推,直到s+m-1小于或等于数组长度。令s+m-2=d,此时,所要被删除的数为A[d]。输出A[d]。然后将A[d]后面的元素都提前一位,用A[d+1]覆盖A[d]来删除A[d]。
循环链表法。构造好循环链表后,找到第s个结点,即结点数据为s的结点。令指针p指向第s个结点,然后循环,每次p=p—>next,直到顺延m次后,p指向所需被删除的结点。然后将此结点删除,并使p=p—>next。以此类推,直到只剩下一个结点,输出此结点。
5、程序测试方案与测试结果
向量法。最大人数为100。依次输入n(人数)回车s(起始数)回车m(顺延数)回车。
结果:输出从1到n的数组后显示出列的顺序。
循环链表法。依次输入n(人数)回车s(起始数)回车m(顺延数)回车。
结果:输出从1到n的链表结点数据后显示出列的顺序。
附录:设计文档与程序源代码;
向量法à
#include <stdio.h>
void main()
{
int n,m,s,d,i,j,l,a[100],dq(int d,int l);
scanf("%d%d%d",&n,&s,&m);
for(i=0;i<n;i++)
{a[i]=i+1;
printf("%d ",a[i]);}
printf("/n");
l=n;
while(l)
{
if(s+m-1<=l)
d=s+m-2;
else
d=s+m-l-2;
d=dq(d,l);
printf("%d ",a[d]);
for(j=d;j<=l-2;j++)
a[j]=a[j+1];
if(d+1!=l)
s=d+1;
else
s=1;
l--;
}
}
int dq(int d,int l)
{
if(d+1>l)
{d--;
d=dq(d,l);}
else
return(d);
}
循环链表法à
#include <stdio.h>
#include <malloc.h>
#define NULL 0
#define LEN sizeof(struct yue)
struct yue
{
int num;
struct yue * next;
};
int n;
struct yue *head;
struct yue * creat(void)
{
int i;
struct yue * head;
struct yue * p1,* p2;
p1=p2=(struct yue *)malloc(LEN);
scanf("%d",&n);
p1->num=1;
head=NULL;
for(i=0;i<n;)
{
i=i+1;
if(i==1) head=p1;
else p2->next=p1;
p2=p1;
p1=(struct yue *)malloc(LEN);
p1->num=i+1;
}
p2->next=head;
return(head);
}
void output(struct yue *p,int n)
{
int i=1;
while(i<=n)
{
printf("%d ",p->num);
p=p->next;
i++;
}
printf("/n");
}
void del(struct yue *head,int s,int m)
{
int u;
struct yue * p3,* p4;
p3=head;
while(s!=p3->num)
{
p3=p3->next;
}
while(p3->next!=p3)
{
u=1;
while(u<m)
{
p4=p3;
p3=p3->next;
u++;
}
printf("%d ",p3->num);
p4->next=p3->next;
p3=p3->next;
}
printf("%d ",p3->num);
}
void main()
{
int s,m;
struct yue *head1;
head1=creat();
scanf("%d%d",&s,&m);
output(head1,n);
del(head1,s,m);
}