解决 约瑟夫 问题。现在 输出 约瑟夫 序列(重复 直到所有人 出列 )如n=8,m=4,s=1 则序列:4,8,5,2,1,3,7,6

现在 输出 约瑟夫 序列(重复 直到所有人 出列 )

n表示 有多少人,m表示报数为几出列,s表示最开始从第几个人(多少编号)开始(1~n的编号都可能)
如n=8,m=4,s=1 则序列:4,8,5,2,1,3,7,6 

/*
解决 约瑟夫 问题。
每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。
他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。) 

现在 输出 约瑟夫 序列(重复 直到所有人 出列 )
如n=8,m=4,s=1 则序列:4,8,5,2,1,3,7,6 
*/
//#include <iostream>
//using namespace std;

#include <stdio.h>
#include <malloc.h>//包含 malloc 函数 

typedef struct person{
	int index;
	struct person *next;
}person;//构建 人 的 的属性,即有多少人 就构建 多少个 结点 

//构建 单链表 
person* generate_link(int n)
{
	printf("star: \n");
	person *q,*p1,*head;
	
	p1 = (person *)malloc(sizeof(person));//申请第一个 元素的空间 
	p1->index = 1;
	int i = 2;
	
	
	head = p1;//保存 首结点地址 ,这个 指针始终 指向首结点 
	
	n = n - 1;
	while(n --)
	{

		//造 q结点 
		q = (person *)malloc(sizeof(person));//申请元素的空间 
		
		q->index = i ++;
		q->next = NULL;
		
		//连接 q结点 
		p1->next = q;
		p1 = q;
		q = q->next;
	}
	
	//首位 相结 贪吃蛇 循环单链表 
	p1->next = head;
	printf("end: \n");
	return head;
}
void josephus_solve(person *head,int m,int s)
{
	int count = 1;
	person *begin = head;
	
	while(begin->index != s)
	{
		begin = begin->next;
	}
	
	printf("序列: ");
	person *q;//记录 要出列 的人 方便 释放空间 
	while(begin != NULL)
	{
	    
		count ++; //报数 
		
		//这里 count 已经 经过了 前面 的count ++ 实际 是下一位 该 报的数 
		if(count == m)//这里,即看他 下一个人 是否报数 m,是 直接让下一个人出列 
		{
			count = 1;//初始 下一个为 起点 
			printf("%d ",begin->next->index);
			q = begin->next;
			begin->next = begin->next->next;
			free(q);
		}
		
		begin = begin->next;
		
		//只有一个 结点,直接 出列 
		if(begin->next == begin)//(循环 单链表 指向 自己 说明 没有其他结点)
		{
			printf("%d ",begin->index);
			break; 
		}
		
	}
	
	printf("\n");
	return;
}

int main()
{
	int n = 0,m = 0,s = 0;
	person *p1;
	printf("n,m,s :");
	scanf("%d%d%d",&n,&m,&s);
	
	//构建 单链表 
    p1 = generate_link(n);
	//开始 处理 得 到 序列 
	josephus_solve(p1,m,s);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_47991812/article/details/121324935