设计一个求解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");

}

posted @ 2020-08-05 23:23  天宇爱水  阅读(188)  评论(0编辑  收藏  举报