Joseph问题:
有10个小朋友按编号顺序1,2,、、、,10顺时针方向围成一圈。从1号开始顺时针方向1,2,、、、,9报数,凡报数9者出列(显然,第一个出圈为编号9者)。
最后一个出圈者的编号是多少?第5个出圈者的编号是多少?
#include <iostream>
using namespace std;
typedef struct _LinkNode{
int data;
struct _LinkNode* next;
}LinkNode,LinkList;
bool initList(LinkList* &L){
L = new LinkNode;
if (!L) return false;
L->next = L; //头结点自己指向自己,形成循环链表
L->data = -1;
return true;
}
//尾插发
bool listInsert_back(LinkList* &L,LinkNode *node) {
if (!L || !node) return false;
if (L==L->next){
node->next = L;
L->next = node;
return true;
}
LinkNode* last=NULL;
last = L->next;
while ((last->next) != L) last = last->next;
node->next = last->next;
last->next = node;
return true;
}
//
void listPrint(LinkList* &L) {
LinkNode* p;
p = L->next;
while (p != L){
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
//解决约瑟夫问题
bool joseph(LinkList* &L, int interval) {
LinkNode *p = NULL, *q = NULL;
int i = 0, j = 0; //i:报数
int times = 0; //圈数,次数
int num = 0; //
p = L;
if (!L || p->next==L){
cout << "链表为空" << endl;
return false;
}
if (interval < 1){
cout << "报数淘汰口令不能小于1!" << endl;
return false;
}
do {
i += interval;
while (p->next){
if (p->next != L) j++;
if (j >= i) break;
p = p->next;
}
times++;
q = p->next;
num = q->data;
if (times == 5) cout << "第5个出圈的编号是:" << num << endl;
printf("cur:%d last:%d next:%d\n", q->data, p->data, q->next->data);
p->next = q->next;
delete q; //释放被删除节点的空间
listPrint(L);
} while (L->next != L);
cout << "最后一个出圈的编号:" << num << endl;
return true;
}
int main() {
LinkList* L = NULL;
LinkNode* node = NULL;
int num;
if (initList(L)){
cout << "LinkList初始化成功" << endl;
}else{
cout << "LinkList初始化失败" << endl;
system("pause");
return -1;
}
for (int i=0;i<10;i++)
{
node =new LinkNode;
node->data = i + 1;
node->next = NULL;
if (listInsert_back(L, node)){
cout << "插入成功!"<<endl;
}
else {
cout << "插入失败!"<<endl;
}
}
listPrint(L);
//解答约瑟夫问题
joseph(L,9);
system("pause");
return 0;
}