您的位置:首页 > 编程语言 > C语言/C++

[C++学习笔记]链表应用2约瑟夫环问题

2012-11-12 22:41 429 查看
问题是:

已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

很明显是用 循环链表实现。

问题1:

节点需要几个部分?这里有编号 所以才有出队的顺序。 编号总共有n个。

我觉得应该两个个 分别存放指针,编号。报数操作可以通过函数实现并且更为合理。

问题2:

有参构造函数里的参数应该是什么?我直接用了n表示位置;

问题3:

如何实现从编号为k的人开始报数 删除数到的那个人。这是这个算法里面最难的地方,我在这个问题纠结了一定的时间,试过很多方法。发现问题的时候还是觉得自己不够耐心,没有好好检查自己的代码导致浪费这么时间。本质原因还是自己思路不够清晰。

很明显,不能使用空头结点。

代码如下:

#include<iostream>

using namespace std;

struct Node{

int num;//编号

Node*next;

};

class Josephus{

friend void printff(Josephus a,int k,int m);

public:

Josephus();

Josephus(int n);

// void print();

int getnumber();

private:

Node*first;

int Number;

};

Josephus::Josephus(){

first=NULL;

first->next=first;

Number=0;

}

Josephus::Josephus(int n)

{

Number=n;

Node*p;

first=new Node;

first->num=1;

first->next=first;

for(int i=n;i>=2;i--){

p=new Node;

p->next=first->next;

first->next=p;

p->num=i;

}

}

int Josephus::getnumber(){

return Number;

}

//void Josephus::print(){

// Node*p;

// p=first;

// for(int i=1;i<=Number;i++){

// cout<<p->num;

// p=p->next;

// }

//}

void printff(Josephus a,int k,int m){

Node*p;

Node*r;

p=a.first;

cout<<"输出顺序为:"<<endl;

if(k==1)

{

r=p;

while(r->num!=a.Number)

r=r->next;

for(int i=0;i<a.Number;i++){

p=r->next;

for(int j=1;j<m;j++){

r=p;p=p->next;

}

cout<<p->num;

r->next=p->next;

delete p;

}

}

else{

while(p->num!=k-1)p=p->next;

r=p;p=p->next;

for(int i=0;i<a.Number;i++){

p=r->next;

for(int j=1;j<m;j++){

r=p;p=p->next;

}

cout<<p->num;

r->next=p->next;

delete p;

}

}

}

int main(){

Josephus A(9);

// A.print();

printff(A,1,5);

return 0;

}

说实话,虽然写的很烂,但是写出来自己还是很开心。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: