问题描述:
编号为1,2,……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序求出出列顺序。
基本要求:
利用单项循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
测试数据:
m的初始值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序为:6,1,4,7,2,3,5)。
代码:
// Child.h
struct Child {
int id; // 编号
int passwd; // 密码
};
// Node.h
#include "Child.h"
struct Node {
Child* child;
Node* next;
};
// CircleLinkList.h
#include "Node.h"
class CircleLinkList {
public:
CircleLinkList();
void append(Child* child);
Child* remove(int index);
bool isEmpty();
~CircleLinkList();
private:
Node* rear; // 尾指针
int length;
};
// CircleLinkList.cpp
#include "CircleLinkList.h"
CircleLinkList::CircleLinkList() {
rear = 0;
length = 0;
}
void CircleLinkList::append(Child *child) {
Node* n = new Node;
n->child = child;
if (!rear) n->next = n;
else {
n->next = rear->next;
rear->next = n;
}
rear = n;
++length;
}
Child* CircleLinkList::remove(int index) {
Node* p = rear;
Node* f = 0;
for (int i = -1; i < index % length - 1; ++i)
p = p->next;
if (p->next == p) {
f = p;
rear = 0;
}
else {
f = p->next;
p->next = p->next->next;
if (p != rear)
rear = p;
}
Child* child = f->child;
delete f;
--length;
return child;
}
bool CircleLinkList::isEmpty() {
return rear == 0;
}
CircleLinkList::~CircleLinkList() {}
// main.cpp
#include "CircleLinkList.h"
#include <iostream>
int main() {
using namespace std;
CircleLinkList l;
cout << "Please input the password of each child by order:" << endl;
int id = 1;
int passwd;
while (cin >> passwd) {
Child* c = new Child();
c->id = id;
c->passwd = passwd;
l.append(c);
++id;
}
int m = 20;
while (!l.isEmpty()) {
Child* c = l.remove(m - 1);
id = c->id;
m = c->passwd;
delete c;
cout << id;
if (!l.isEmpty()) cout << ", ";
}
cout << endl;
return 0;
}