第三章 详细设计
3.1 主函数
Main()这这Menu这这这这这这这这1这这这这这这这这这2这这这这这这这这这这这这这这这这这这这这3这这这这这这这这这这n这这这这这这这这n这这这这这这这这这这这这这这这这这这这这这这这这这这这cresteLise(&ppHead,n) jose(ppHead,m);这这这这这这这这这这这
图4 主函数数据流程图
根据图4,主函数程序如下: int main() {
int n,m,x;
LNode *ppHead=NULL; menu(); for(;;) {
printf(\请选择要执行的操作:\ scanf(\
system(\ switch(x) {
case 1:
printf(\ printf(\约瑟夫环:\\n\
printf(\编号为1,2,3,4?,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数).一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始按顺序报数,报到m时停止.报m的人出列,将他的密码m作为新的m值,从他的顺时针方向上的下一人开始重新从1报数,如此下去,直到所有人全部出列为止.编程打印出列顺序.\\n\
printf(\ main(); break; case 2:
printf(\请输入总人数n:\\n\ scanf(\
printf(\请输入开始上限数m:\ scanf(\
createList(&ppHead,n); printf(\
printf(\出队顺序:\\n\ jose(ppHead,m);
printf(\约瑟夫环游戏结束!\\n\ main(); break; case 0: exit(0); default:
system(\
printf(\您选择的操作有误,请重新选择...\\n \ main(); } } return 0; }
3.2 链表的创建
这这这这这这这这这这这这这这这这Main()这这createList();这这这这这这这这这这这n这这n>0这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这main()
图5 创建链表函数的数据流程图
/*创建单向循环链表ppHead,参加人数个数为n,并输入每人的密码值,若建立失败则生成头结点,让cur指向他,若建立成功则插入结点P,cur指向的数据元素为p,后续为\空\的结点,再把P插入循环链表ppHead中*/ 根据图5,创建链表函数程序如下:
void createList(LNode **ppHead,int n) { int i,m_pwd;
LNode *p,*cur;//cur:浮标指针 for(i=1;i<=n;i++) {
printf(\输入第%d个人的密码:\
scanf(\输入持有密码 p=createNode(i,m_pwd);//调用构造结点函数 if(*ppHead==NULL)//如果头结点为空 { *ppHead=cur=p;//生成头结点,让cur指向他 cur->next=*ppHead;//cur的指针域指向自身 } else//如果不为空,则插入结点 { p->next = cur->next; cur->next = p; cur= p;//cur指向新插入结点 } } printf(\完成创建!\\n\提示链表创建完成 }
3.3 出队处理
Main()这这Jose():这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这这i=ppHead->pwd;j=ppHead->num;这这这这这这m_pwd=ppHead->pwd;这这这这这这这这这这这这这这这这这这这这这这这这free(ppHead);ppHead=p->next;这这这这这这这这这
图6 出对函数的数据流程图
/*p指向要删除结点的前一个结点,ppHead指向要删除的结点,使p=ppHead,ppHead再指向要删除结点的下一个结点,使p和ppHead链接,输出p指向结点的编号和密码值,释放ppHead,如此循环,直至把所有结点都打印和删除为止!*/
根据图6,出队函数程序如下:
void jose(LNode *ppHead,int m_pwd) {
int i,j;
LNode *p;//定义指针变量 for(i=1;p!=ppHead;i++) {
for(j=1;j { p=ppHead;//p赋值为ppHead,p指向要删除结点的前一个结点 ppHead=ppHead->next;//ppHead指向下一个元素 } p->next = ppHead->next;//p结点与头结点链接 i=ppHead->pwd;//i赋值为ppHead->pwd j=ppHead->num;//j赋值为ppHead->num,j为要删除的密码值 printf(\第%d个人出列,密码:%d\\n\ m_pwd=ppHead->pwd;//m_pwd赋值为ppHead->pwd free(ppHead);//释放头结点 ppHead=p->next;//ppHead重新赋值给p->next,即释放前的ppHead->pwd指针//删除报数结点 } i=ppHead->pwd;//i赋值为ppHead->pwd j=ppHead->num;//j赋值为ppHead->num printf(\最后一个出列是%d号,密码是:%d\\n\ free(ppHead);//释放头结点 } 3.4 约瑟夫环说明模块 void instruction() { printf(\ printf(\约瑟夫环:\\n\ printf(\编号为1,2,3,4?,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数).一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始按顺序报数,报到m时停止.报m的人出列,将他的密码m作为新的m值,从他的顺时针方向上的下一人开始重新从1报数,如此下去,直到所有人全部出列为止.编程打印出列顺序.\\n\ printf(\} 3.5菜单模块 void menu() { printf(\约瑟夫环***********************\\n\ printf(\ printf(\约瑟夫环问题的阐述 \\n\ printf(\按要求求解约瑟夫环 \\n\ printf(\退出 \\n\ printf(\欢迎使用!*********************\\n\}