/******************************************
* 文件名:dnode.cpp
* 作用: 1, 实现双向循环链表
2, 用双向循环链表解决Josephus问题
* 创建日期: 2007-9-24
******************************************/
#include <iostream>
using namespace std;
template <typename T>
class dnode
{
public:
dnode()
{
init();
}
dnode(const T &v):value(v)
{
init();
}
private:
void init()
{
prev = this;
next = this;
}
public:
T value;
dnode<T> *prev;
dnode<T> *next;
};
/**********************************
* Insert()
* 入口参数: dnode<T> *curr, const T &v
* 功能: 在curr前面插入一个value = v 的结点
**********************************/
template <typename T>
void Insert(dnode<T> *curr, const T &v)
{
dnode<T> *newNode = new dnode<T>(v);
/* 先将newNode与curr->prev 连接 */
curr->prev->next = newNode;
newNode->prev = curr->prev;
/* curr 与newNode 连接 */
newNode->next = curr;
curr->prev = newNode;
}
/*******************************************
* erase()
* 入口参数:dnode<T> *curr;
* 功能: 从链表中删除curr结点
*******************************************/
template <typename T>
void erase(dnode<T> *curr)
{
/* 1,curr与curr->prev解除关系
* 2,curr->prev 与curr->next连接
* 3, delete curr
*/
curr->prev->next = curr->next;
curr->next->prev = curr->prev;
curr->prev = 0;
curr->next = 0;
delete curr;
}
/*******************************************
* clear()
* 入口参数:dnode<T> *header
* 功能: 清空链表内容
*******************************************/
template <typename T>
void clear(dnode<T> *header)
{
while(header->next != header)
erase(header->next);
}
/******************************************
* display()
* 入口参数:dnode<T> *header
* 功能:输出链表内容
******************************************/
template <typename T>
void display(dnode<T> *header)
{
dnode<T> *curr;
curr = header->next;
if (curr == header)
{
cout << "Empty!" << endl;
return ;
}
while( curr != header)
{
cout << curr->value << ' ';
curr = curr->next;
}
}
/*******************************************
* josephus()
* 入口参数:int n, int m;
* 功能:约瑟夫问题. 一个一个输出来
*******************************************/
void josephus(int n, int m)
{
dnode<int> *dList, *curr;
dList = new dnode<int>();
int i;
for( i = 1; i <= n; i++)
Insert(dList, i);
curr = dList->next;
while((dList->prev != dList) && (dList->prev != dList->next))
{
for(i = 1; i < m; i++)
{
curr = curr->next;
if(curr == dList) /* 越过头结点 */
curr = curr->next;
}
cout << " delete : " << curr->value << endl;
curr = curr->next;
erase(curr->prev);
if(curr == dList)
curr = curr->next;
}
cout << curr->value << " win! " << endl;
delete curr;
delete dList;
}
int main()
{
int n, m;
cout << "Enter the n : ";
cin >> n;
cout << "the gap m : ";
cin >> m;
josephus(n, m);
return 0;
}
当n = 6, m = 3时
输出为:
Enter the n : 6
the gap m : 3
delete : 3
delete : 6
delete : 4
delete : 2
delete : 5
1 win!