猴子选大王循环链表实现

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C++

n只猴子围成一圈,顺时针方向从1到n编号。之后从1号开始没顺时针方向让猴子从1,2,...,m依次报数,凡是报到m的猴子,就让其出圈,取消候选资格。然后不停地按顺时针方向逐一让报到m者出圈,是的剩下的一个就是猴王。

#include

using namespace std;

struct monkey //结构声明

{

int num; //整型数,用于记录猴子号

monkey *next; //monkey结构指针

};

monkey *head,*tail; //monkey结构指针,全局变量

void creat(int nn) //被调用函数

{ //函数体开始

int i; //整型变量i,用于计数

monkey *p,*q; //声明monkey结构指针p,q

p=new monkey; //为p分配内存空间

p->num=1; //初始化p结点num域为1

p->next=NULL; //初始化p结点next域为空

head=p; //链表头指针head赋值为p

q=p; //q赋值为p

for(i=2;i<=nn;i=i+1) //利用循环结构构造链表

{

p=new monkey; //为p配内存空间

p->num=i; //初始化p结点num域为i,表示猴子号

q->next=p; //将p点加到链表尾部

q=p; //让指向链表尾部结点

p->next=NULL; //链表尾部指向空

}

tail=q; //链表尾

tail->next=head; //链表尾部指向链表头,形成循环链表

}

//被调用函数select,mm表示结点删除间隔

void select(int mm)

{ //函数体开始

int x=0; //声明整型值x,并初始化为0

monkey *p,*q; //声明指针变量p,q

q=tail; //q赋值给tail,指向循环链表尾部

do //直到型循环,用于循环删除指定间隔的结点

{

p=q->next; //p赋值给相邻的下一个结点

x=x+1; //x加1

if(x%mm==0) //x是否整除mm

{

cout<<"被删除的猴子号为"<num<<"号\n";

q->next=p->next; //删除此结点

delete p; //释放空间

p=NULL;

}

else

q=p; //q指向相邻的下一个结点p

}while(q!=q->next); //剩余结点数不为1,则继续循环

head=q; //head指向结点q,q为链表中剩余的一个结点

} //函数体结束

int main() //函数体开始

{

int n,m; //声明整型变量n,m

head=NULL; //初始化head为空

cout<<"请输入猴子的个数\n"; //提示信息

cin>>n; //输入待插入结点的数据

cout<<"请输入间隔\n"; //提示信息

cin>>m; //输入间隔

creat(n); //调用函数creat建立循环链表

select(m); //调用函数select,找出剩下的猴子

cout<<"猴王是"<num<<"号\n"; //输出猴王

delete head; //删除循环中最后一个结点

return 0;

} //函数体结束

c

//实现目标:分别列出出列的猴子,然后得出最后的大王,(我认为没必要猴子数m要大于n!..所以没有这方面的提示~~)

//问题分析:通过对“猴子选大王”问题的分析,由于本题目的数据元素的个数不可预知,所以使用链表。链表是动态的,可以在需要的时候增长和减少其长度,而数组是在编译时分派内存的,事业其大小是不可改变的,而且会出现内存浪费的情况。我认为单循环链表能较好,在建立循环链表时,因为链表的大小由输入决定,因此与匹配的结点数也是变化的,所以要进行动态内存分配。

//测试用例:m=10;n=4,最后求出成为猴王的猴子号:结果:大王是5号:(太搞笑了,大家都用这个用例,第五号可真幸运!~)

//不健全的地方:1.没有对输入为字母,非正数(例如0)进行出错判断,结果大王会是第一号猴子。(我觉得也可以不改啊~~没有“正常的”猴子,下一个真正的猴子当然是大王)2.如果正数但是非整数,输出为……(我没试过=——=!)

//猴子选大王源代码:

#include"stdio.h"//用双引比尖括号好的原因是可以在本环境外部查找这个头文件滴..

#include"stdlib.h"

typedef struct Node

{

int data;

struct Node *next;

}Node,*LinkList;

void CreatLinkList(LinkList *L,int m)// 创建循环链表 m为猴子总数

{

Node *p, *q;

int i; (*L) = (LinkList)malloc(sizeof(Node));

if ((*L) == NULL)//这里是什么意思?

{

printf("Memory allocation failed,goodbye~~");

exit(1);

}

p = (*L);

p->data = 1;//为什么错误数据会返回“第一号猴子”的值?是这里初始化的么?(如果是可以换成0的说~)

for (i = 2; i <= m; i++)

{

q = (LinkList)malloc(sizeof(Node));

if (q == NULL)

{

printf("Mmory allocation failed,goodbye~~");

exit(1);

}

q->data = i;

p->next = q;

p = q;

相关文档
最新文档