约瑟夫问题
示例
初始人数:5
初始编号:3
人的序号:1、2、3、4、5
自杀序号:3、1、2、5、4
先上运行结果
源代码如下
#include<iostream>
using namespace std;
class Node {
public:
int e;
Node* next;
Node(int x, Node* n = NULL) :e(x), next(n) {}
Node() :next(NULL) {}
};
class Clist {
public:
Clist() { head = curr = tail = NULL; }
~Clist() { while (head != NULL) { curr = head; head = head->next; delete curr; } }
void append(int it); //将各位的编号添加到循环链表中
void print(); //将已经得到的编号在屏幕上显示出来
void kill(int n); //由当前的编号开始报数,杀死第n个人
private:
Node* head, * curr, * tail;
int length(); //求当前总人数
void remove(int& it); //将当前指针curr之后的一个结点移除,并将其标号返回
};
int Clist::length() {
if (head == NULL) return 0;
if (head == head->next) return 1;
Node* temp = head->next;
int n = 1;
while (temp != head) {
n++;
temp = temp->next;
}
return n;
}
void Clist::append(int it) {
if (head == NULL) {
head = curr = tail = new Node(it);
head->next = head;
return;
}
Node* temp = new Node(it);
temp->next = tail->next;
tail->next = temp;
tail = tail->next;
}//此函数将编号为it的结点添加到循环链表中
void Clist::remove(int& it) {
if (head->next == head) { it = head->e; head = curr = tail = NULL; return; }
Node* temp = curr->next;
curr->next = temp->next;
if (temp == head) head = tail = curr;
//if (temp->next == head) tail = curr;
it = temp->e;
delete temp;
}
void Clist::print() {
if (head == NULL)return;
Node* temp = head;
do {
cout << temp->e << '\t';
temp = temp->next;
} while (temp != head);
cout << endl;
}//此函数将自杀人中的所有编号在屏幕上显示出来
void Clist::kill(int n) {
while (head != NULL) {
if (n == 1) {
int l = length();
for (int i = 1; i < l; i++) curr = curr->next;
int x;
remove(x);
cout << x << '\t';
curr = curr->next;
kill(x);
}
else if (n == 2) {
int x;
remove(x);
cout << x << '\t';
curr = curr->next;
kill(x);
}
else {
for (int i = 0; i < n - 2; i++) curr = curr->next;
int x;
remove(x);
cout << x << '\t';
curr = curr->next;
kill(x);
}
}
cout << endl;
}//此函数将自杀人的序号在屏幕上显示出来
const int M = 5;//初始人数
const int N = 3;//初始自杀编号
int main() {
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };//初始编号,注意为正整数(1、2、3……)
Clist clist;
for (int i = 0; i < M; i++) clist.append(a[i]);
cout<<"初始人数为:"<<M<<'\n'<<"初始编号为:"<<N<<endl;
cout<<"初始人的标号为"<<endl;
clist.print();
cout<<"自杀人的序号为"<<endl;
clist.kill(N);
return 0;
}