设计一个求解Josephus问题的算法
1 使用SeqList.h:用整数序列1,2,...,n表示顺序围坐在原桌周围的人。
int Josephus(SeqList &L,int s,int m){
int i,j,k=L.n;
for(i=0;i<L.n;i++){L.data[i]=i+1;}//数组初始化,记入编号
i=(s-1)%L.n;
while(k>0){//执行A.n趟,删除A.n人
i=(i+m-1)%k;printf("%d\t",L.data[i]);//报数m,输出第m个人编号
for(j=i+1;j<k;j++){L.data[j-1]=L.data[j];}//压缩
k--;
}
printf("\n");
}
//2 带头结点的循环单链表求解Josephus问题。
int Josephus(CircList &list,int s,int m,int n){
//算法中s是起始结点号,m是报数间隔,n是最初人数
CircList p=list->link,pr=list;int i,j;
for(i=1;i<s;i++){p=p->link;}//指针p进到第s个结点
for(i=0;i<n;i++){//执行n次
for(j=1;j<m;j++){//数m-1个人
pr=p;p=p->link;
if(p==list){pr=p;p=p->link; }//若*p为头结点则跳过
}
printf("%d\t",p->data);//输出
pr->link=p->link;free(p);//删除p结点
p=pr->link;//下一次报数从下一结点开始
if(p==list){pr=p;p=p->link;}//若*p为头结点则跳过
}
printf("\n");//换行
}
//3 带头结点的循环双链表求解Josephus问题。
int Josephus(DblList &list,int s,int m,int n){
DblList p=list->rLink,q;int i,j;
for(i=1;i<s;i++){p=p->rLink;}//指针p进到第s个结点
for(i=0;i<n;i++){//循环n次,让第n个人出列
for(j=1;j<m;j++){//让p向后移动m-1次
if(p->rLink != list){p=p->rLink;}
else{p=list->rLink;}
}
printf("%d\t",p->data);
p->lLink->rLink=p->rLink;//从链表中摘下p所指的结点
p->rLink->lLink=p->lLink;
q=(p->rLink==list)?list->rLink:p->rLink;
free(p);p=q;//删除结点*p后p改之后继节点
}
printf("\n");
}