C语言循环链表求解约瑟夫环问题(循环方式)

/**************************************************************************************************
* @brief:	使用链表和循环求解约瑟夫环问题。找出每次出局者的编号。
* @author:	wuchuan <wuchuanlove@qq.com>.
* @date:	2013-4-23.
**************************************************************************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

typedef struct YSF_LINK_T
{
	int number;
	struct YSF_LINK_T *next;
}ysf_link_t;

//根据人数n创建单向环形链表,编号从1到n。
ysf_link_t *create_link(int n)
{
	if (n < 2)
		return NULL;

	int i = 0;
	ysf_link_t *head = NULL;
	ysf_link_t *cur = NULL;
	ysf_link_t *ptr = NULL;

	for (i=0; i<n; i++)
	{
		ptr = (ysf_link_t *)malloc(sizeof(ysf_link_t));
		if (ptr)
		{
			ptr->number = i + 1;
			ptr->next = NULL;
			if (NULL == head)
				head = cur = ptr;
			else
			{
				cur->next = ptr;
				cur = cur->next;
			}
		}
		ptr = NULL;
	}
	//尾节点与首节点相连,形成环
	cur->next = head;
	
	return head;
}

//create_link()测试
void print_link(void)
{
	ysf_link_t *pup = NULL;
	ysf_link_t *head = create_link(5);

	cout << head->number << endl;
	for (pup=head->next; pup!=head; pup=pup->next)
		cout << pup->number << endl;
	return;
}

//compile: vs2010
//求解约瑟夫环过程
int main(int argc, char *argv[])
{
	//print_link();

	int i = 0;
	int n, k, m;

	cout << "input n(n>=3):";
	cin >> n;
	cout << "input k(1<=k<=n):";
	cin >> k;
	cout << "input m(m>=2):";
	cin >> m;
	cout << "you input: n=" << n << ", k=" << k << ", m=" << m << endl;
	if (n<3 || k<1 || k>n || m<2)
		exit(1);

	ysf_link_t *cur = NULL;
	ysf_link_t *prev = NULL;
	ysf_link_t *head = create_link(n);

	cur = head;
	while ((++i < k) && cur)
		cur = cur->next;
	
	i = 0;
	while (cur)
	{
		if (++i == m)
		{
			//输出每次出局者的编号
			cout << cur->number << ", ";
			//如果已经是最后一个节点,释放后跳出循环
			if (cur == cur->next)
			{
				free(cur);
				cur = NULL;
				break;
			}
			//释放出局者节点,重新开始计数
			prev->next = cur->next;
			free(cur);
			cur = prev->next;
			i = 0;
			continue;
		}
		prev = cur;
		cur = cur->next;
	}
	cout << endl;
	prev = cur = NULL;

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,约瑟夫环问题可以使用循环链表来解决。具体实现步骤如下: 1. 定义一个循环链表结构体,包括数据域和指向下一个节点的指针。 2. 根据参与游戏的人数n,创建一个含有n个节点的循环链表,并将它们连接成一个环形。 3. 定义一个指针p指向链表的头节点,并让它依次指向链表中每一个节点,直到p指向最后一个节点。 4. 定义一个计数器count,每次p指向下一个节点时,count加1。 5. 当count的值等于m时,将p指向的节点从链表中删除,并将count重置为0。 6. 重复执行步骤4和5,直到链表中只剩下一个节点为止,该节点即为游戏的胜者。 下面是C语言的实现代码: ```c #include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node* next; } Node; // 创建循环链表 Node* createCircularLinkedList(int n) { Node* head = NULL, *p = NULL, *tail = NULL; for (int i = 1; i <= n; i++) { p = (Node*)malloc(sizeof(Node)); p->data = i; if (i == 1) { head = p; } else { tail->next = p; } tail = p; } tail->next = head; return head; } // 在循环链表中删除节点 Node* deleteNode(Node* head, Node* p) { if (head == NULL) { return NULL; } if (p == head) { head = head->next; } else { Node* q = head; while (q->next != p) { q = q->next; } q->next = p->next; } free(p); return head; } // 约瑟夫环问题 void josephus(int n, int m) { Node* head = createCircularLinkedList(n); Node* p = head; int count = 0; while (p->next != p) { count++; if (count == m) { printf("%d ", p->data); head = deleteNode(head, p); p = head; count = 0; } else { p = p->next; } } printf("%d\n", p->data); free(p); } int main() { int n = 5, m = 3; josephus(n, m); return 0; } ``` 以上代码实现了约瑟夫环问题求解,其中createCircularLinkedList函数用于创建循环链表,deleteNode函数用于在循环链表中删除节点,josephus函数用于解决约瑟夫环问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值