您的位置:首页 > 理论基础 > 数据结构算法

数据结构--约瑟夫环(含密码,C++实现)

2017-10-21 12:21 597 查看
///*约瑟夫环问题是:编号为1,2······,n的n个人按顺时针方向围坐一圈,每人持有一个密码。

***一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,

***报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下

***一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

***利用链式存储结构模拟此问题,按照出列顺序打印各人的编号

***测试数据: m的初值为20,n=7,七个人的密码依次为3,1,7,2,4,8,4。则首先出列的值为6

***                     依次正确的出列顺序应该为6,1,4,7,2,3,5。

*///

<实现代码>

#include <iostream>

using namespace std;

struct People{        

    int number;         //people的编号
    int password;     //每人持有一个密码
    People *next;      //创建链表节点people

};

class Joseph{                              //循环单链表的创建

private:
    int m_iPeopleNumber;           //参与的人数
    int m_iDeleteNumber;            //要删除的序号
    int m_iOverNumber;                //报数上限

    People *head;                          //链表的头结点

public:

    Joseph(int peopleNumber,int deleteNumber,int overNumber);
    ~Joseph();
    bool game();

};

Joseph::Joseph(int peopleNumber,int deleteNumber,int overNumber){
    m_iPeopleNumber = peopleNumber;
    m_iDeleteNumber = deleteNumber;

    m_iOverNumber = overNumber;
    People *temp1,*temp2;                                                                           //创建空指针

  
    for(int i = 1; i <= m_iPeopleNumber; i++){                                            //for循环用于初始化环 
        int inputPassword;
        cout<<"please enter NO."<<i<<" people's password:";
        cin>>inputPassword;

        temp1 = new People;

        temp1->number = i;

        temp1->password = inputPassword;

        if(i == 1){    //如果当前链表为空,头指针指向第一个人  
            head = temp1; 
            temp2 = temp1;

        } 

        //否则,temp2永远指向尾结点,新建立的结点都插入到temp2之后

        else{                                                                                                        
            temp2->next = temp1;
            temp2 = temp1;
        }
    }
    temp2->next = head;                                                                                 //循环链表的实现

}

Joseph::~Joseph(){

    delete head;
    head = NULL;
}

bool Joseph::game(){                                                                              //游戏开始
    if(m_iDeleteNumber >= m_iOverNumber || m_iDeleteNumber <= 0 ){
       cout<<"Your number is over!!"<<endl;
   return false;
    }
    People *temp1,*temp2,*temp;                                                         //创建空指针

     //用count定位到第m_iPeopleNumber个人,循环后,temp1指向这个人,temp2指向这个人的上一个人

    temp1 = head;
    int count;                                                                               
    int a = m_iDeleteNumber;                                                                //赋初值
    for(int i = 1; i <= m_iPeopleNumber; i++){                                     //游戏次数是人数减去一
       count = 1; 
       while(count < a){
           temp2 = temp1;
           temp1 = temp1->next;

           count ++;

        }

        cout<<"Delete it:"<<temp1->number<<endl;                  //出局人的编号
        temp = temp1;
        a = temp->password;                                                         //记录密码,用来删除下一个人
        temp2->next = temp1->next;                                             //将当前出局人的直接前驱和直接后继连接起来
        temp1 = temp->next;                                                          //下次从当前人的下一个人开始数
        delete temp;                                                                         //释放内存
    }
    cout<<endl;
    head = NULL;                                                                      //游戏结束没有人剩余
    return true;
}

int main(){

    int peopleNumber,deleteNumber,overNumber;

    cout<<"please enter overNumber:";
    cin>>overNumber;
    cout<<"please enter peopleNumber:";
    cin>>peopleNumber;
    cout<<"please enter deleteNumber:";
    cin>>deleteNumber;

    Joseph J1(peopleNumber,deleteNumber,overNumber);
    J1.game();

    return 0;
}

<运行结果>

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息