顺序表的应用1--josephus问题
题目:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列……如此反复直到所有的人全部出列为止。Josephus问题是:对于任意给定的n,s和m ,求出按出列次序得到的n个人员的序列
思路:采用顺序表模拟。可以用整数i来代替n(i),将初始序列改写成一个整数的序列1,2,3,……,n,并把它们存储在一个palist所指顺序表中,当s<=n时,第s个人放在palist->element[s-1]之中,因此第一个报数出列的应该是下标为s-1+m-1对n取模后的元素,如果这个下标为i ,出列工作只要将palist->element[i]从顺序表中删除,然后对palist->element[0],palist->element[1],……从下标i 开始重复上述过程。
算法的定义如下:
#include <stdio.h> #include "stdlib.h" #define Maxnum 100 typedef int DataType; struct SeqList { int MAXNUM;//顺序表中最大的元素个数 int n;//顺序表中元素的个数 DataType * element;//线性表中的元素 }; typedef struct SeqList * PSeqList;
顺序表的增删改查
//创建空顺序表 PSeqList createNullList_seq(int m) { PSeqList palist=(PSeqList)malloc(sizeof(struct SeqList)); if (palist!=NULL) { palist->element=(DataType *)malloc(sizeof(DataType) * m); if(palist->element) { palist->MAXNUM=m; palist->n=0; return palist; } else { free(palist); } } printf("out of space!! \n"); return NULL; } //顺序表的插入,在palist所指顺序表中下标为p的元素之前插入元素x int insertPre_seq(PSeqList palist,int p,DataType x) { DataType * pos1; int q; if(palist->n>=palist->MAXNUM) { //顺序表空间的扩展 pos1=(DataType*)malloc(sizeof(DataType)*palist->MAXNUM*2); if(pos1==NULL) { printf("Overflow!"); return 0; } for(q=0;q<palist->MAXNUM;q++) { pos1[q]=palist->element[q]; } free(palist->element); palist->element=pos1; palist->MAXNUM*=2; } if (p<0||p>palist->n) { printf("Not Exist!! \n"); return 0; } for(q=palist->n-1;q>=p;q--) { palist->element[q+1]=palist->element[q]; } palist->element[p]=x; palist->n=palist->n+1; return 1; } //顺序表的删除,在palist所指顺序表中删除下标为p的元素 int deleteP_seq(PSeqList palist,int p) { int q; for(q=p;q<palist->n-1;q++) { palist->element[q]=palist->element[q+1]; } palist->n=palist->n-1; return 1; }
Josephus算法
//s表示开始报数人,m 表示出列的人 void josephus_seq(PSeqList palist,int s,int m) { int s1,i,w; //数组从0开始算起,所以s要减去1; s1=s-1; for(i=palist->n;i>0;i--) { s1=(s1+m-1)%i;//求模 //求下标为s1的元素的值 w=palist->element[s1]; //元素出列 printf("Out element %d \n",w); //删除出列的元素 deleteP_seq(palist,s1); } }
测试:
int main() { PSeqList jos_aList; int i,k; int n,s,m; printf("\n please input the values(<100)of n="); scanf("%d",&n); printf("please input the value of s="); scanf("%d",&s); printf("please input the value of m="); scanf("%d",&m); jos_aList=createNullList_seq(n); if(jos_aList!=NULL) { //为链表的元素赋值; for(i=0;i<n;i++) { insertPre_seq(jos_aList,i,i+1); } josephus_seq(jos_aList,s,m); free(jos_aList->element); free(jos_aList); } return 1; }
结果如下:

浙公网安备 33010602011771号