約瑟夫問題,雙向鏈表實現

問題描述:N個人圍城一圈,從第一個人開始報數,第M個被殺掉,最後剩下一個人,其餘人都排除

/*
鏈表
*/

#include <iostream>
#include <stdlib.h>
using namespace std;

//雙向鏈表
template <typename T>
class dnode{
public:
	T nodeValue;
	dnode<T> *prev;
	dnode<T> *next;

	dnode()
	{
		next = this;
		prev = this;
	}
	dnode(const T& value) :nodeValue(value){}
};

template <typename T>
void writeDLinkedList(dnode<T> *header)
{
	dnode<T> *p = header->next;

	while (p != header)
	{
		cout << p->nodeValue << " ";
		p = p->next;
	}

}

template <typename T>
dnode<T> *insert(dnode<T> *curr, const T& item)
{
	dnode<T> *newNode, *prevNode;

	newNode = new dnode<T>(item);

	prevNode = curr->prev;

	newNode->prev = prevNode;
	newNode->next = curr;

	prevNode->next = newNode;
	curr->prev = newNode;

	return newNode;
}

template <typename T>
void erase(dnode<T> *curr)
{
	if (curr->next == curr)
		return;

	dnode<T> *prevNode = curr->prev, *succNode = curr->next;

	prevNode->next = succNode;
	succNode->prev = prevNode;
	
	delete curr;
}



void josephus(int n, int m)
{
	dnode<int> *header = new dnode<int>, *curr;
	int i, j;

	for (i = 1; i <= n; i++)
		insert(header, i);

	curr = header->next;

	for (i = 1; i < n; i++)
	{
		writeDLinkedList(header);
		for (j = 1; j <= m - 1; j++)
		{
			curr = curr->next;

			if (curr == header)
				curr = curr->next;
		}
		cout << "Delete node " << curr->nodeValue << endl;

		curr = curr->next;
		erase(curr->prev);

		if (curr == header)
		{
			curr = curr->next;
		}
	}
	
	cout << "Win node " << curr->nodeValue << endl;

	delete curr;
	delete header;

}
void main()
{
	int n, m;
	cin >> n;
	m = rand() % n + 1;
	cout << "n m:" << n << " " << m << endl;
	josephus(n, m);


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章