猴子选大王

    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;
  }