一、 需求分析
1. 本演示程序中,限定约定约瑟夫的节点数和密码均不超过100,每个节点的密码均不超过节点个数的两倍,且为方便起见所有密码均根据时间动态生成,程序需输入的有:①生成约瑟环的节点数,②程序的初始密码;若输入超出界,则起用默认值:10
2. 程序执行的命令有:输入约瑟夫环的节点和初始密码,约瑟夫环的初始化及动态生成,约瑟夫环的运行演示
3. 程序测试:正确输入测试,条件边界输入测试,超边界输入测试
二、 概要设计
4. 为实现题目要求功能,用单向循环链表来表示约瑟夫环
5. 约瑟环中没释放掉一个环节点,则对应在循环链表中释放掉该节点
6. 当剩下最后一个节点时,我们不再进行释放,而是输出,得到我们想要的结果!
三、 详细设计
1. 定义节点数据结构体:
typedef struct{
int num; /*The num for Joseph struct*/
int password; /*Password for Joseph struct*/
}SElemType;
2. 定义节点结构体,用来创建循环链表:
typedef struct Joseph{ /*The Node for the ring of Joseph*/
SElemType elem;
struct Joseph *next;
}Joseph;
3. 节点初始化函数的定义,用来初始化链表节点:
int InitList(Joseph *l){ /*Initial the the node*/
l=(Joseph *) malloc (sizeof(Joseph));
if(!l)
return OVERFLOW;
return OK;
}
4. 约瑟夫链表节点的空间释放:
void FreeNode(Joseph *p){/*Free the node have been deleted*/
Joseph *temp=p;
while(temp->next!=p)
temp=temp->next;
temp->next=p->next;
printf("The node of num:%3d is free "n",p->elem.num);
free(p);
}
5. 约瑟夫链表的创建以及随机初始化节点数据域数据:
void Creat_Joseph(Joseph *l,int length){/*creat the password of node by rand()*/
int i;
Joseph *p=l;
l->next=l;
l->elem.num=1;
srand( (unsigned)time(NULL));
l->elem.password=rand()%(length+3)+1;
printf("The flowing is the Joseph Ring created by rand():"n");
printf("The Node num: %3d Password: %3d"n",l->elem.num,l->elem.password);/*print the first node of the ring of Joseph*/
for(i=1;i<length;i++){
Joseph* temp=(Joseph*)malloc (sizeof(Joseph));
p->next=temp;
temp->next=l;
temp->elem.num=i+1;
temp->elem.password=rand()%(2*length)+1;
printf("The Node num: %3d Password: %3d"n",temp->elem.num,temp->elem.password);/*print all the node of the ring of Joseph expect the first one*/
p=p->next;
}
}
6. 约瑟夫问题实际过程演示:
void Joseph_Run(Joseph *l, int m){/*do node free by password of node*/
int i,k;
Joseph *temp,*p;
if(l->next==l)
printf("The last Node num is: %d",l->elem.num);/*Print the last Node*/
else{
temp = l;
for(i=1; i<m; i++)
temp=temp->next;
p=temp->next;
k=temp->elem.password;
FreeNode(temp);/*Free The unusefull Node*/
Joseph_Run(p,k);/*Using The Recursive Functions*/
}
}
7. 主函数的描述:
void main(){
int num=10;
int m=10;
Joseph *J_list;
printf("Please input the total num of Joseph Nodes( less than 100):");/*input the total num of Joseph Nodes*/
scanf("%d",&num);
if(num<=0||num>=100){
printf("What your input is not accepted,so using 10 instead!"n");/*Using the default to instead*/
num=10;
}
printf("Please input the first node num (less than 100):");/*input the first node num*/
scanf("%d",&m);
if(m<=0||m>=100){
printf("What your input is not accepted,so using 10 instead!"n");/*Using the default to instead*/
m=10;
}
InitList(J_list);
Creat_Joseph(J_list,num);
Joseph_Run(J_list,m);
}