C++利用循环单链表解决约瑟夫环问题

有n个元素,编号从1号开始一直到n号,形成一个环,从第k号开始报数,报到m的出列,直到所有元素都出列为止。

要求:n,k,m的值由用户输入,调用函数实现。

测试数据:

例:10个元素,从1号开始,报到3的元素出列。则出列顺序为:3,6,9,2,7,1,8,5,10,4;

10个元素,从5号开始,报到1的元素出列。则出列顺序为:5,6,7,8,9,10,1,2,3,4;

100个元素,从20开始,报到33的元素出列,则出列顺序是什么?

以测试数据1为例:

C++利用循环单链表解决约瑟夫环问题_第1张图片

-------------------------------------------------------------------------------------

定义单链表数据结构

#include 
using namespace std;

typedef int ElemType;
typedef struct LNode 
{
	ElemType data;
	LNode* next;
} LinkNode;

1.初始化循环单链表

void InitNode (LinkNode*& L)
{
	L = new LinkNode;
	L-> next = L;
}

C++利用循环单链表解决约瑟夫环问题_第2张图片 

2.尾插法建立循环单链表

void CreateListByRear (LinkNode*& L, LinkNode*& r, ElemType arr[], int n) 
{
	r = L;     				// 尾指针并指向头节点
	L->data = arr[0];       // 头节点的data赋值
	
	for (int i = 1; i < n; ++i) // 新建节点并插入数据
    {       
		LinkNode* s = new LinkNode;
		s->data = arr[i];
		r->next = s;
		r = s;
    }
	r->next = L;
}   

 C++利用循环单链表解决约瑟夫环问题_第3张图片

 3.输出出圈顺序

pre指针指向p的前驱结点,方便销毁结点后,连接下一个结点。

void out(LinkNode*& p, LinkNode*& pre, int count, int move) 
{
	int i = 1;
	
//  移动节点,到开始的那个数
	while (--move) {
		p = p->next;
		pre = pre->next;
	}
	
//  当圈不为1个人时,循环出圈
	while (p->next != p)
    {
		
		if (i == count) // 数到某个数,就出圈
        {       
			i = 1;
			cout << p->data << " ";
			
			pre->next = p->next;    // 删除出圈节点
			delete p;
			p = pre->next;
			
		} 
        else
        {
			pre = pre->next;        // 如果没数到指定的数,就继续移动,并统计
			p = p->next;
			++i;
		}
	}
	cout << p->data << endl;        // 输出圈的最后一个数
}

--------------------------------------------------------------------------------------主函数

int main() 
{
// 1. 定义头尾节点指针, 初始化头节点指针
	LinkNode* head; InitNode(head);
	LinkNode* rear;
	
// 2.定义, 输入需要的参数; 初始化数组并赋值
	int n, m, from;
	cout << "请输入元素个数: "; cin >> n;
	cout << "从第几个人开始? "; cin >> from;
	cout << "第几个人出圈? "; cin >> m;
	int* a = new int[n];        // 创建动态数组

	for (int i = 0; i < n; ++i) {   // 把元素插入到数组中
		a[i] = i + 1;
	}
	
//  3. 尾插法创建循环单链表并得到尾指针
	CreateListByRear(head, rear, a, n);
	
//  4. 出圈并输出
    cout << "出圈顺序为: ";
	out(head, rear, m, from);
	
//  5. 出圈后仅剩头节点,释放头节点指针所指空间即可
	delete head;
	
	return 0;
}

你可能感兴趣的:(数据结构,算法,c++,c语言)