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

循环链表

最近开始复习数据结构,今天手写了一个约瑟夫循环问题。

什么是循环链表

循环链表

首尾相连的链表:head->last=tail;tail->next=head
建立循环链表和建立普通链表方法差不多,只需要首尾相连即可

约瑟夫循环问题

已知 n 个人(以编号1,2,3,…,n分别表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列;他的下一个人又从 1 还是顺时针开始报数,数到 m 的那个人又出列;依次重复下去,要求找到最后出列的那个人。
例如:5个人,编号依次为12345,从第3个人开始报数,报到2的退出,然后下一个接着从开始报数
那么退出的顺序是:4-1-3-2-5

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

思路:从第k个节点开始,将第m-1个节点释放,连接好链表即可。

C++实现


#include<iostream>
#include<cstdlib>
using namespace std;
#include<string>
struct list {
	struct list* next;
	struct list* last;
	int data;//编号
};
struct list* creat(int n)//创建循环链表
{
	struct list* head,*tail,*normal;
	head = new list;
	tail = new list;
	head = tail;//不需要这一句
	cout << "请输入数据" << endl;//头结点的数据
	cin >> head->data;
	for (int i = 1; i < n; i++)
	{
		normal = new list;
		cout << "请输入数据" << endl;
		cin >> normal->data;
		tail->next = normal;//尾节点连接新创建的节点
		normal->last = tail;//新创建的节点的上一个是尾节点
		tail = normal;//将尾节点移动到新创建的节点
	}
	head->last = tail;//首尾相连
	tail->next = head;//首尾相连
	return head;
}
void delPerson(struct list* p) {//功能函数
	struct list* head, * tail;//不需要用到head,后面的head都可以省去
	head = new list;
	tail = new list;
	head = p;
	int k;
	cout << "请输入K" << endl;
	cin >> k;
	while (p->data != k)//从第k个人开始报数
	{
		tail = p;
		p = p->next;
	}
	cout << "请输入m" << endl;
	int m;
	int i = 0;
	cin >> m;
	while (tail->next != tail)//如果不是只剩最后一个节点
	{
		for (i = 0; i < m-1; i++)
		{
			tail = p;
			p = p->next;
		}
		tail->next = p->next;//tail的next连接p的next
		p->next->last = tail;//p的下一个的上一个是tail
		cout << "删除的编号是:" << p->data << endl;
		free(p);//释放p
		p = tail->next;//p移动到tail的next
	}
	cout << "删除的编号是:" << tail->data<<"\n";
}
int main()
{
	struct list* p;
	p = new list;
	int n;
	cout << "请输入总人数" << endl;
	cin >> n;
	p = creat(n);
	delPerson(p);
	system("pause");
	return 0;
}

运行效果

运行结果

猜你喜欢

转载自blog.csdn.net/qq_45049373/article/details/106975894
今日推荐