C语言 Jesephus问题 (链表链栈实现)猴子选大王


你的老师留这个作业了吗?

1.题目

编程题:Jesephus问题(猴子选大王)
有n个人围一圈,从第s人开始数数,s为1,依次数到m,m出局,至最后一人为主。
要求:
用c语言编写一程序,读入n,s,m,建立一个循环链表,每个节点依次装入自然数1,2,……,n,
实现上述操作,且每一个出圈者加入同一链栈中,最后输出大王序号,及依出局次序号。``
qq-735429101

2.题目分析

很明确的告知了是Jesephus问题,从选人的过程来说,我们选用循环链表来操作,为什么是链表而不是数组?
1.链表可以很好的把n个人连成一个圈
2.对选出的序号,链表也更易实现删除操作
3.题目要求建立循环链表

很明确选人过程用链表即可实现,那么为什么要用链栈?
1.可以用栈来存放选出来的序号
2.出栈的“先进后出”可以实现一个逆序的功能
3.题目要求

总的来说,这是考察Jesephus算法及链表链栈的题目。

3.解题思路分析

1.创建结点,用来表示不同的人,每个结点里面的data类型为int型,目的是存放n个从1开始自然数来表示结点序号。

2.读入n之后,利用循环创建长度为n的循环链表,并为每个结点存入对应的序号。

3.找到选人开始的初始位置,问题指定为s=1。

4.选人过程利用双循环。外循环控制选人次数,当有n个人,那么选出n-1或n个人即可。内循环进行具体选人,利用读入的m对循环进行控制,每当选出一人,就要对该结点进行删除。也可再利用(p->data==(p->next)->data)这样一个条件来判断选人是否结束。

5.利用链栈存储序号。可以先写好入栈函数,把入栈函数放在上面的4中的循环里面,这样就直接把选出来的序号存储到链栈。

6.显示排名。编写出栈函数即可

4.代码及截图检验
#include<stdio.h>
#include<stdlib.h>
/*jesephus问题*/
typedef int datatype;

typedef struct node/*创建结点*/
{
	datatype data;
	struct node *next;
}node;

node *head;
node *top;

void Push(int x)/*入栈函数*/
{  node *p;
   p=(node *)malloc(sizeof(node));
   p->data=x;
   p->next=top;
   top=p;
}
void ShowStack()/*显示栈中所有的元素*/
{ 	node *p;int x=1;
    p=top;
    if(p->data==0)printf("\t\t\t 栈中无元素!\n");
    else
	{
		while(p->data!=0)
		{
			printf("名次 %03d 序号 %2d\n",x,p->data);
			p=p->next;
			x++;
		}
    }
}
int main()
{
	int n,m,s,i,j;
	printf("请依次输入总人数n,自然数m。(用空格隔开)\n");
	scanf("%d%d",&n,&m);
	s=1;
	printf("\n本题已经指定开始位置为 s=1\n");
	node *p,*q;
	head=(node *)malloc(sizeof(node)); 
	head->next=NULL;
	top=(node *)malloc(sizeof(node)); 
	top->next=NULL;
	top->data=0;
	p=head;/*指针p指向头结点*/
	i=n;j=1;
	while(i)
	{
		q=(node *)malloc(sizeof(node)); /*为新结点q申请分配内存*/
		q->data=j++;/*读入数据*/
		q->next=p->next;/*q结点指针域指向p结点指针域*/
		p->next=q;/*指向新的结点*/
		p=q;
		i--;
	}
	printf("\n");
	p->next=head->next;/*循环链表,最后一个结点指向第一个结点*/
	p=head;/*指针p指向头结点*/
	i=s-1;
	while(i)/*找到指定位置s=1*/
	{
		p=p->next;
		i--;
	}
	j=1;int x=1;
	while(j)/*选人*/
	{
		i=m-1;
		while(i)
		{
			p=p->next;
			i--;
		}
		q=p->next;
		printf("第%2d个入栈为 序号%d\n",x,q->data);
		Push(q->data);
		x++;
		p->next=q->next;
		free(q);
		if(p->data==(p->next)->data)j=0;
	}
	Push(p->data);
	printf("第%2d个入栈为 序号%d\n\n",x,p->data);
	ShowStack();
	return 0;
}

qq-735429101
欢迎指点交流!

写稿不易,感谢支持!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值