C语言数据结构——用链表处理约瑟夫问题

题目链接如下:
tOpenJudge - 1748:约瑟夫问题


问题描述:

约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入输出要求:

输入:需能同时输入多组数据,以0 0结尾标志着结束。

样例输入:6 2  12 4  8 3  0 0

样例输出:5 1 7

解决思路:

1.由于猴子围成了一个圈,故此处使用循环链表的数据结构,将每只猴子看作是一个结点,用序号表示。

//建立结点数据结构 
typedef struct node
{
	int data;
	struct node *next;
}Node,*Link;
for(i=0;i<n;i++)//尾插法生成循环链表 
{
	p = (Link)malloc(sizeof(Node));
	p->data = i+1;
	tail->next = p;
	p->next = head->next;
	tail = p;
}

2.当猴子报数为m时,将该猴子所表示的结点删除,并将下一个结点(猴子)标号为1,看作是下一趟报数的起点。

if(i==m)
{
	q->next = p->next;
	free(p);
	p = q->next;
	i = 1;//第二趟报数 
}

3.如果不是m号猴子,不改变结点,指针指向下一结点。

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//建立结点数据结构 
typedef struct node
{
	int data;
	struct node *next;
}Node,*Link;

int main()
{
	int n,m,count,i;
	//定义头结点head 
	Link head,tail,p,q;
	head = (Link)malloc(sizeof(Node));
	head->next = NULL;
	
	while(1)
	{
		scanf("%d %d",&n,&m);
		if(n==0&&m==0)//结束条件 
		{
			free(head);
			break;
		}
		else
		{
			tail = head;
			for(i=0;i<n;i++)//尾插法生成循环链表 
			{
				p = (Link)malloc(sizeof(Node));
				p->data = i+1;
				tail->next = p;
				p->next = head->next;
				tail = p;
			}
			p = head->next;//p指向第一个结点 
			q = tail;//q指向最后一个结点

            i = 1;
			while(p!=q)//出列 
			{
				if(i==m)
				{
					q->next = p->next;
					free(p);
					p = q->next;
					i = 1;//第二趟报数 
				}
				else//q指针在p指针之前,如果两个指针重合,说明只剩下一个结点 
				{
				    q = p;
					p = p->next;
					i++;	
				} 
			}
			printf("%d\n",p->data);
			free(p); 	 
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值