约瑟夫环程序

                  昨天编了一个约瑟夫环的小程序,用的循环链表。

 

#include  < iostream >
using   namespace  std;
struct  Boys          // Boys作为节点的结构体
{
    
int m_number;
    Boys 
*next;

    Boys(
int number = 1, Boys *link = NULL) : m_number(number), next(link)
    
{
    }

}
;

class  Rings            // 环类 
{
private:
    Boys 
*pCurrent;   //当前指针
    Boys *pBegin;     //指向头节点的指针
    Boys *pre;        //前驱指针,主要用于孩子出圈,也就是循环链表删除节点

public:

    Rings()          
//构造函数建立头节点
    {
        pBegin 
= new Boys;
        pBegin
->next = pBegin;
        pCurrent 
= NULL;
    }


    
void Insert(const int n)        //循环链表节点的插入
    {
        Boys 
*= pBegin;

        
for(int i = 2; i<=n; i++)   //由于头节点的m_number初始化为1,所以后面的节点从2开始
        {
            pCurrent 
= new Boys(i);
            pCurrent
->next = q->next; //插入
            q->next = pCurrent;
            q 
= pCurrent;
        }


        pCurrent 
= pBegin;       //令当前节点重新指向头节点
    }


    
void PrintList()             //输出循环链表
    {
        cout
<<"全体打印孩子如下:"<<endl;

        Boys 
*= pBegin;

        
do
        
{
            cout
<<p->m_number<<"  ";
            p 
= p->next;

        }
while(p != pBegin);
    }


    
void CountBoy(int m)      //数间隔
    {
        
for(int i = 1; i <= m; i++)
        
{
            pre 
= pCurrent;    //pre指针指向pCurrent的前驱,用于节点的删除
            pCurrent = pCurrent->next;
        }

    }


    
void ClearBoy()
    
{
        pre
->next = pCurrent->next; //删除节点
        delete pCurrent;            //释放节点
        pCurrent = pre;             //pCurrent重新指向刚才被删除节点的前驱节点
                                    
//以备继续数间隔
    }


    
void PrintOneBoy()              //输出一个出圈的孩子号码
    {
        cout
<<pCurrent->m_number<<"  ";
    }


    
~ Rings()
    
{
        delete pCurrent;
    }

}
;

class  Jose              // Jose类
{
private:
    
int m_numofBoys;  //孩子总数
    int m_beginPos;   //数孩子的起始位置
    int m_distance;   //数孩子的间隔

public:

    Jose(
int boys = 10int begin = 1int distance = 3)
    
{
        m_numofBoys 
= boys;
        m_beginPos 
= begin;
        m_distance 
= distance;
    }


    
void InitJose()     //初始化操作,通过人工输入将Jose的3个数据成员赋值
    {
        
int boys, begin, distance;

        cout
<<"输入孩子的数目:"<<endl;
        cin
>>boys;
        cout
<<"您想从哪个孩子的号码开始:"<<endl;
        cin
>>begin;
        cout
<<"您希望每次查数的间隔是:" <<endl;
        cin
>>distance;
        
        m_numofBoys 
= boys;
        m_beginPos 
= begin;
        m_distance 
= distance;
    }


    
void GetWinter()                  //核心程序,求胜利者
    {
        Rings myRings;
        myRings.Insert(m_numofBoys);  
//插入建立循环链表
        myRings.PrintList();          //打印循环链表

        myRings.CountBoy(m_beginPos 
- 1);   //查找开始位置

        cout
<<endl<<"出圈次序依次为:"<<endl;
        
for(int i = 1; i < m_numofBoys; i++//依次出圈
        {
            myRings.CountBoy(m_distance);    
//数间隔
            myRings.PrintOneBoy();           //输出出圈的孩子
            myRings.ClearBoy();              //将出圈的孩子从链表中删除
        }


        cout
<<endl<<"最后的胜利者是:"<<endl;
        myRings.PrintOneBoy();            
//最后的胜利者
    }


}
;

main()
{
    Jose myJose;
    myJose.InitJose();   
//获得用户输入
    myJose.GetWinter();  //输出结果
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值