约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始循环转圈报数,每次的第M个人将退出,。例如N=6,M=5,退出圈的顺序依次是:5,4,6,2,3,1
由于退圈的工作涉及到频繁的删除工作,所以选用循环单链表结构。
约瑟夫问题的实现代码:
// 创建一个无头节点的、有n个节点的、循环单链表
node* create(int n)
{
if (n < 0)
{
return NULL;
}
int index = 1;
node* pHead = new node[n];
if (NULL == pHead)
{
return NULL;
}
else
{
memset(pHead, 0, n*sizeof(node)); //初始化内存
}
node* p = pHead;
while (index < n)
{
p->data = index;
p->next = p + 1;
p = p->next;
index++;
}
p->data = n;
p->next = pHead;
return pHead;
}
void josephus_problem(int n, int m)
{
node* pHead = create(n);
node* p = pHead;
m %= n; // 确保n大于m
while (p != p->next) // 链表中的节点数大于1
{
for (int count = 1; count < m - 1; count++)
{
p = p->next;
}
cout << p->next->data << " ";
p->next = p->next->next; // 删除节点 p.next
p = p->next;
}
cout << p->data << endl;
delete []pHead;
}