单向循环链表 解决约瑟夫问题

单向循环链表  解决约瑟夫问题

约瑟夫问题为:设编号为1,2,……n得n个人围坐一圈,约定编号为k(k大于等于1并且小于等于n)的人从1开始报数,数到m的那个人出列。它的下一位继续从1开始报数,数到m的人出列,依次类推,最后剩下一个为猴王。

"[code:c]"
#include <stdio.h>
#include <stdlib.h>

typedef struct node_t
{
	int data;
	struct node_t *next;
}link_node_t,*link_list_t;

int main(int argc, const char *argv[])
{
	int i;
	link_list_t pdel = NULL;//用于指向被删除节点
	link_list_t ptail = NULL;//永远指向当前链表的尾 
	link_list_t pnew = NULL;//永远指向新创建的节点
	link_list_t h = NULL;
	int all_num = 7;//猴子总数 
	int start_num = 2; //从几号猴子开始数
	int kill_num = 3;//数到几杀死猴
	// printf("请您入猴子总数 起始号码 数到几杀死:\n");
	// scanf("%d%d%d",&all_num,&start_num,&kill_num);
	//1.创建出一个单向循环链表
	//(1)创建有all_num个节点的单向链表
	h = (link_list_t)malloc(sizeof(link_node_t));
	if(NULL == h)
	{
		perror("malloc failed");
		return -1;
	}
	h->data = 1;
	h->next = NULL;
	ptail = h;//尾指针指向当前的第一个节点
	for(i = 2; i <= all_num; i++)
	{
		//创建新的节点
		pnew = (link_list_t)malloc(sizeof(link_node_t));
		if(NULL == pnew)
		{
			perror("malloc failed");
			return -1;
		}
		//将新节点装上数据
		pnew->data = i;
		pnew->next = NULL;
		//将新节点链接到链表尾 
		ptail->next = pnew;//链接到链表的尾
		ptail = pnew;//尾指针继续指向当前链表的尾 
	}
	//(2)将头指针保存到链表的尾形成单向循环链表
	ptail->next = h;//形成单向循环链表 
#if 0 //用于调试程序
	while(1)
	{
		printf("%d\n",h->data);
		h = h->next;
		sleep(1);
	}
#endif
	//2.开始杀猴子 
	//(1)将头指针移动到开始猴子的号码处 
	for(i = 0; i < start_num-1; i++)
		h = h->next;
	//(2)循环进行杀猴子
	while(h != h->next)//条件不成的时候,就剩一个猴子,只有一个节点
	{
		//将头指针移动到即将删除节点的前一个节点
		for(i = 0; i < kill_num-2; i++)
			h = h->next;

		pdel = h->next;
		//跨过删除节点
		h->next = pdel->next;
		printf("kill is -------------%d\n",pdel->data);
		free(pdel);
		pdel = NULL;
		//杀死猴子猴,从下一个节点开始继续开始数,将头指针移动到开始数的地方
		h = h->next;
	}
	printf("king is=================== %d\n",h->data);
	return 0;
}	

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是单向循环链表约瑟夫问题的代码实现: ``` #include <iostream> using namespace std; // 定义单向循环链表节点 struct Node { int data; // 数据域 Node* next; // 指针域 Node(int val = 0) : data(val), next(nullptr) {} // 构造函数 }; // 定义单向循环链表类 class CirLinkedList { public: CirLinkedList(); // 构造函数 ~CirLinkedList(); // 析构函数 void CreateList(int n); // 创建长度为n的单向循环链表 void Josephus(int m); // 约瑟夫问题,每m个节点删掉一个 private: Node* first; // 链表头指针 }; CirLinkedList::CirLinkedList() { first = nullptr; // 初始化链表为空 } CirLinkedList::~CirLinkedList() { // 释放链表内存 Node* temp = first; while (temp) { Node* p = temp; temp = temp -> next; delete p; } } void CirLinkedList::CreateList(int n) { if (n < 1) return; first = new Node(1); // 创建第一个节点 Node* temp = first; // 创建剩余的n-1个节点 for (int i = 2; i <= n; ++i) { Node* p = new Node(i); temp -> next = p; temp = temp -> next; } temp -> next = first; // 最后一个节点指向头结点,形成单向循环链表 } void CirLinkedList::Josephus(int m) { // 如果链表为空,直接退出 if (first == nullptr) return; Node* pre = nullptr; // pre指向待删除节点的前一个节点 Node* cur = first; // cur指向待删除节点 // 找到待删除节点,确保链表中至少有两个节点 while (cur -> next != cur) { // 移动m-1步,找到待删除节点 for (int i = 0; i < m - 1; ++i) { pre = cur; cur = cur -> next; } pre -> next = cur -> next; // 将待删除节点从链表中删除 cout << cur -> data << " "; // 输出删除的节点 delete cur; // 释放删除的节点内存 cur = pre -> next; // 更新待删除节点为下一个节点 } // 输出链表剩余节点 cout << cur -> data << endl; } int main() { int n, m; cin >> n >> m; // 输入链表长度n和每次删掉的节点数m CirLinkedList cll; cll.CreateList(n); // 创建单向循环链表 cll.Josephus(m); // 解决约瑟夫问题 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值