循环链表—约瑟夫环问题

  假设n个人决定选出一个领导,将所有人排成一个圆圈,沿着这个圆圈每次数到M个人就排除对应着者,每当有人出列后,其余人靠拢,任然保持一个完整的圆圈,。问题就是找出剩下的那个人是谁,这就是所谓的约瑟夫问题。

算法思想:为了以一种循环方式排列人群,我们构建一个循环链表,每个人与循环左边的人之间构成一个链接,整数i表示循环之中第i个人,生成一个唯一节点的循环链表后(即第一个节点的next指向它自己),在该节点后插入2到N个节点,得到一个从1到N的循环然后跳过M-1个节点,删除第M个节点,依次循环,直到只剩下最后一个节点,就是要寻找的那个数。

                                                                                 

                                                                

                                                                    

#include <stdio.h>
#include <stdlib.h>
struct Node{
	int data;
	struct Node *next;
}; 
typedef struct Node link;
int main(){
	int m, n, i;
	scanf("%d%d", &m, &n);
	link *t, *x;
	t = (link *)malloc(sizeof(link));
	t -> data = 1;
	t -> next = t;
	x = t;
	for(i = 2; i <= m; i++){
		x -> next = (link*)malloc(sizeof(link));
		x = x -> next;
		x -> data = i;
		x -> next = t;
	}
	while(m != 1){
		for(i = 1; i < n; i++){
			x = x -> next;
		} 
		x -> next = x -> next -> next;
		m--;
	}
	printf("%d", x -> data);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值