约瑟夫问题C++求解

#include <iostream>

using namespace std;

struct child
{
    int id;
    child *nextChild;
    child *preChild;
};

class Game
{
    private:
        int sum;
        int k;
        child first;
    public:
        Game(int sum,int k)
        {
            this->sum = sum;
            this->k = k;
            first.id = 1;
        }

        void createCycleLink()
        {
            child temp = first;

            int num = 2;
            while(num!=sum)
            {
                child node;
                node.id = num++;
                temp.nextChild = &node;
                node.preChild = &temp;
                temp = node;
            }
            child node;
            node.id = sum;
            first.preChild = &node;
            node.nextChild = &first;
        }

        void gameStart()
        {
            child temp = first;
            while(sum!=1)
            {
                int count = 1;
                while(count<k)
                {
                    count++;
                    temp = *temp.nextChild;
                }
                child kill = temp;
                child kill_next = *kill.nextChild;
                child kill_pre  = *kill.preChild;
                kill_next.preChild = &kill_pre;
                kill_pre.nextChild = &kill_next;
                cout<<kill.id<<"  ";
                temp = kill_next;
                sum--;
            }
            cout<<endl<<temp.id<<endl;
        }

};

int main()
{
    Game game(10,1);
    game.createCycleLink();
    game.gameStart();
    return 0;
}

 

上面的代码是错误的,我用struct构造双向循环链表,有问题。

其实约瑟夫问题根本就是不需要构建双向循环链表的,只是需要单向循环链表就行了。

 

#include<cstdio>
#include<cstdlib>
struct Jonse
{
    int code;
    Jonse *next;
};

Jonse *createCycleLink(int sum)
{
    Jonse *head,*p;
    int i;
    head = (Jonse *)malloc(sizeof(Jonse));
    p = head;
    for(i=1;i<=sum;i++)
    {
        p->code = i;
        if(i<sum)
        {
           p->next = (Jonse*)malloc(sizeof(Jonse));
           p = p->next;
        }
            }
    //p->code = sum;
    p->next = head;
    return head;
}

Jonse *gameStart(Jonse *head,int m)
{
    //q 一直指向p的前一个节点
    Jonse *p,*q;
    p = head;
    while(p!=p->next)
    {
        for(int i=1;i<m;i++)
        {
            q = p;
            p= p->next;
        }

        printf("%d\t",p->code);
        //重新构造循环链表
        q->next = p->next;

        //释放p节点
        free(p);
        p = NULL;

        //从下一个节点重新开始
        p = q->next;
    }
    printf("\nThe winner is %d\n",p->code);
    return head;

}

void showList(Jonse *head)
{
    Jonse *p;
    p = head;
    do
    {
        printf("%d\t",p->code);
        p = p->next;
    }while(p!=head);
}
int main()
{
    Jonse *head = createCycleLink(10);
    gameStart(head,2);
    //showList(head);
    return 0;
}



 

上面的约瑟夫问题代码可以说是很优美的了

总之约瑟夫就会一个单向循环链表的问题 注意建表的细节并且在遍历的时候注意保存前面的节点 还有清除节点的过程


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值