猴子选大王
M只猴子要选大王,选举办法如下:所有猴子按1,2……n编号围成一圈,从第一号开始顺序报数1,2……m,凡是报m号的退出圈外,如此循环报数直到圈内只剩一只猴子时这只猴子就是大王。
数据结构:
猴子链表,循环
猴子属性值:判断是否落选
利用单向循环链表模拟此过程,输出选出的大王编号。
程序的设计思想:
(1)问题分析:“猴子选大王”问题是约瑟夫环问题的一个特例。由于本题目的数据元素个数不可知,所以可使用链表来动态的分配内存空间。而该问题又是一个不断的循环问题所以用循环链表来实现。
(2)总体设计:首先生成一个空链表,并给n个结点分配空间,让单链表的表尾指针指向头结点则生成一个带有n个结点的循环单链表。再给每只猴子建立顺序的编号。 现从第一个结点开始报数,依次顺序查找出报数为m的待出列的结点(猴子)通过q->next=p->next删除该结点后继续运行否则让q成 为p的前驱指针。最后当p->next==p时停止运行,得到p所指向的结点即为猴子选出大王的编号。
C语言程序源代码:
#include <stdio.h> #include <stdlib.h> #define n 8 #define m 3 typedef struct monkey { int num; struct monkey *next; } Monkey; int main() { Monkey *p,*head,*q; int i; head=p=q=malloc(sizeof(Monkey));//建立头指针 for(i=1;i<n;i++) //给n个结点分配空间 { p=malloc(sizeof(Monkey)); q->next=p; q=p; } q->next=head; //建立循环链表 p=head; printf("对猴子进行编号!\n"); for(i=1;i<=n;i++) //给n只猴子分别建立顺序编号 { p->num=i; printf("%d号猴子:%d\n",p->num,p->num); p=p->next; } i=0; //初始化 p=head; while(1) { i++; printf("%d号猴子报:%d\n",p->num,i); if(p->next==p) break; //判断还剩下最后一个结点时停止运行 if(i==m) //报道m的猴子淘汰 { i=0; printf("%d号猴被淘汰\n",p->num); q->next=p->next; p=q->next; continue; } else { if(i==m-1) q=p; p=p->next; }