约瑟夫问题解决

问题叙述性说明:有着N人身。离1至N号码,通过环形包围,从第一人1报数,每一个第一M百姓出,人休息继续报告的数量,等等,寻找这个人的最后剩余数量。

上次去的地方写的网络,在测试这个问题,说话的12人身。一圈圈,从第一人报数,1-3,每个报告3人出局,求最后剩下那个人原来的序号。

能够用一个循环链表来解决。将全部人的编号构成一个循环链表。每隔M就删掉一个节点,直到最后剩下一个。

void josephus (int N, int M)
{
	//定义一个节点,当然定义在这里不怎么合适
	struct node {
		int item;
		struct node *next;
	}Node;

	//创建第一个节点
	Node *t = malloc (sizeof (Node));
	Node *x = t;
	t -> item = 1;
	t -> next = t;

	//创建剩下的节点
	for (int i = 2; i <= N; i++)
	{
		Node *new = malloc (sizeof (Node));
		x -> next = new;
		x = x -> next;
		x -> item = i;
		x -> next = t;
	}
	//循环数数,每隔M的人出局
	while (x != x -> next)  //不是最后一个节点
	{
		for (int i = 1; i < M; i++)
			x = x -> next;
		//第M个人出局
                Node *del = x -> next;
                x -> next = x -> next -> next;
                free(del);
                N--;
	}
	//打印最后一个节点
	printf ("%d", x -> item);
        free(x);
 }


版权声明:本文博主原创文章,博客,未经同意不得转载。

转载于:https://www.cnblogs.com/zfyouxi/p/4874356.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值