关于约瑟夫问题(尾指针尾插法)

约瑟夫问题折腾了很久,还询问了别人,最后终于自己敲出了一个自认为完美的解决方案。

虽然我一开始写的代码可以输出结果,但是可能是因为时间超限,原本可能是rear指针移动的原因,直接反映到析构上,这样也好。长见识了,以后如果析构出问题了,就要检查一下指针的相关移动。

难点在于仅用尾指针将结点插在尾部,不用头结点和头指针。

现在这个难点解决了!实际上所有的难点都是建立在基础上的,就像插入节点时需要先将下一个节点的地址保存一样,循环链表中的头结点也没什么不同,不过是每次插入时都要现将头结点的地址赋给新节点的next域。而头结点的地址始终保存在rear指针指向的结点的next域中,所以重中之重是每次一定要移动尾指针以确保尾指针的位置正确。

题目描述:约瑟夫(Joseff)问题求解。n个人围成一圈,编号依次为1, 2....n,从第一个人开始报数,m号出圈,再从下一个开始报数m号出圈,直至所有人出圈。求出圈的次序。要求采用仅设尾指针的单向循环链表实现。已知类的定义、部分成员函数及主函数代码如下(勿改动)。

如下是插入函数的代码:

template 
void LinkList::RInsert(T x)
{
	Node* p;
	p = new Node;//分配空间
	p->data = x;
	if (rear == NULL)
	{
		rear = p;
		p->next = rear;
	}
	else
	{
		p->next = rear->next;
		rear->next = p;
		rear = rear->next;
	}
}

以下是约瑟夫代码:

template 
void LinkList::Joseff(int m)
{
	Node* p;
	if (rear)
	{
		p = rear->next;
		for (int i = 1; p->next != p; i++, p = p->next)
		{
			if (i == m-1 )
			{
				Node* q = p->next;
				p->next = q->next;
				cout << q->data << " ";
				i = 0;
			}
		}
		cout << p->data;
	}
	rear = NULL;
}

 没想到这道约瑟夫的重点却是尾结点尾插法。

不过这种约瑟夫的写法也是简洁明了。

 

 

 

你可能感兴趣的:(数据结构,数据结构,链表,指针,算法,c++)