ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Josephus环问题两种求解算法(C语言实现)

2020-02-03 16:36:52  阅读:327  来源: 互联网

标签:Josephus people int C语言 current 算法 next previous


Josephus环问题两种求解算法(C语言实现)

一、算法一

构造双向循环链表。
首先创建结构体数组,每个结构体包括元素的编号、前驱元的索引(previous)及后继元的索引(next)。每次循环删除一个元素,使该元素的前驱元的next指向后继元的previous,后继元的previous指向前驱元的next,并将此元素标号置为-1。
从被删除元素的下一个元素开始继续循环,直到数组中只剩下一个元素(此元素的previous与next相等)
显然该算法时间复杂度为O(m*n)

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

struct node
{
	int number;      //序号
	int previous;    //前驱元标号
	int next;        //后继元标号
};

struct node* InitArray(int n)//初始化游标形式的双向循环链表
{
	struct node* people = (struct node*)malloc(sizeof(struct node) * n);
	for (int i = 0; i < n; i++)
	{
		people[i].number = i + 1;
		people[i].next = (i + 1) % n;
		people[i].previous = (i + n - 1) % n;
	}
	return people;
}

int Josephus(int n, int m)
{
	struct node* people = InitArray(n);
	int current = m;  
	while ((current != people[current].next))//只剩下一个元素时,结束循环
	{
		printf("%d->", people[current].number);
		people[current].number = -1;
		people[people[current].previous].next = people[current].next;//删去结点,修改指针指向
		people[people[current].next].previous = people[current].previous;
		for (int i = 0; i <= m; i++)
		{
			if (people[people[current].next].number > 0)
			{
				current = people[current].next;
			}
		}
	}
	return people[current].number;
}

int main()
{
	int x;   //初始总人数
	int y;   //相邻两个倒霉的人之间相隔的人数
	printf("初始总人数为:");
	scanf_s("%d", &x);
	printf("相邻两个倒霉的人之间间隔的人数为:");
	scanf_s("%d", &y);
	printf("\n最后幸存的人标号为:%d", Josephus(x, y));

	return 0;
}

二、算法二

首先删除标记为k - 1的人,把最初标记为k的人标 记为0,并从0开始,重新标记其余的标签;
在这里插入图片描述
则有关系式Josephus(n, k) = (Josephus(n - 1, k) + k)) % n;
另有Josephus(1, k) = 0;
据此即可在O(n)时间内完成迭代计算
(代码略)

DarkSide_ 发布了2 篇原创文章 · 获赞 0 · 访问量 14 私信 关注

标签:Josephus,people,int,C语言,current,算法,next,previous
来源: https://blog.csdn.net/DarkSide_/article/details/103857372

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有