猴子大王:
猴子选大王问题是一个十分经典的算法问题,这个问题是这样的:一堆猴子都有编号,编号是1,2,3 ...m,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第N个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。(本代码利用循环链表结构,完成了著名的猴子大王问题,具体代码与思路如下。)
代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode
{
int data;
struct Lnode *next;
}joseph;
void Create_List(joseph *L,int n)
{
joseph *p,*q; //两个指针 p q.
int i;
q=L; //q指向链表L的位置
for(i=2;i<=n;i++){
p=(joseph*)malloc(sizeof(joseph)); //p申请空间
p->data=i; //将i放入p的data中
q->next=p;
q=p; //指针后移
}
p->data=n; //最后一个数存放进去
p->next=L; //建立循环链表.
}
void josephus( joseph *L, int s, int m)
{
int i,j;
joseph *p,*q;
p=L; //此时p已经指向第一个节点
for(i=1;i<s;i++) //找到从s号开始
{
q=p;
p=p->next;
}
while(p->next!=p) //判断链表中有一个以上元素
{
for(j=1;j<m;j++) //指向所需要输出释放的节点
{
q=p;
p=p->next;
}
printf("%d ",p->data); //输出该值
q->next=p->next; //删除
free(p); //释放空间
p=q->next; //p再次指向下一个
}
printf("%d",p->data); //输出最后一个值
free(p);
}
void main()
{
joseph *L=NULL; //确保指针为空
int m,n,s;
L=(joseph*)malloc(sizeof(joseph)); //给链表申请空间
L->data=1; //L的第一个位置存放数字1
printf ("请输入人数、约定编号数,出列值:\n");
scanf ("%d%d%d", &n, &s, &m);
if ((m> 1000) || (n> 1000))
printf ("输入的人数m,n不合法\n");
else
if (s>n) printf ("输入数据不合法!\n");
else
{
Create_List(L, n);
printf ("\n");
josephus(L,s,m);
}
}