约瑟夫问题,双向链表实现

问题描述:N个人围城一圈,从第一个人开始报数,第M个被杀掉,最后剩下一个人,其余人都排除

/*
链表
*/

#include 
#include 
using namespace std;

//双向链表
template 
class dnode{
public:
	T nodeValue;
	dnode *prev;
	dnode *next;

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

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

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

}

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

	newNode = new dnode(item);

	prevNode = curr->prev;

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

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

	return newNode;
}

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

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

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



void josephus(int n, int m)
{
	dnode *header = new dnode, *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);


}


你可能感兴趣的:(C++,算法学习)