1.利用循环链表实现约瑟夫问题的求解。
例题:已知n个人(以编号1,2,3,……,n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。试用C++编程实现。
数据存储结构:
循环链表,将一个链表的尾元素指针指向队首元素:
p->link = head;
解决问题的核心步骤如下:
(1)建立一个具有n个链节点、无头节点的循环表。
(2)确定第1个报数人的位置。
(3)不断地从链表中删除链节点,直到链表为空。
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#define ERROR 0
using namespace std;
typedef struct LNode
{
int data;
struct LNode *link;
}LNode,*LinkList;
void JOSEPHUS(int n,int k,int m)
{
LinkList p,r,curr;
//建立循环链表
p = (LinkList)malloc(sizeof(LNode));
p->data = 0;
p->link = p;
curr = p;
for(int i = 1;i < n;i++)
{
LinkList t = (LinkList)malloc(sizeof(LNode));
t->data = i;
t->link = curr->link;
curr->link = t;
curr = t;
}
//把当前指针移动到第一个报数的人
r = curr;
while(k--)
{
r = p;
p = p->link;
}
while(n--)
{
for(int s = m-1;s--;r = p,p = p->link)
;
r->link = p->link;
cout << p->data << endl;
free(p);
p = r->link;
}
}
int main()
{
JOSEPHUS(13,4,1);
cin.get();
return 0;
}