约瑟夫(Josephus)环问题(c++单向循环链表实现)

约瑟夫(Josephus)环问题:

编号为1,2,3,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一人开始重新从1报数,如此下去,直到所有人全部出列为止。建立n个人的单循环链表存储结构,运行结束后,输出依次出队的人的序号。

思路

将n个人的password依次输入,将每个人的id,password,next写入一个结构体,形成链表的一个节点,写入并创建为单循环链表。

然后再进行循环删除列表元素,记得free防止memory leak

另外注意当m == 1并且当前节点为head时情况处理有所不同需要拿出讨论。

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<mm_malloc.h>

using namespace std;

typedef struct LNode
{
    
    
    int id;
    int password;
    struct LNode *next;
}LNode,*LinkList;   //节点指针变量和头指针

int a[10000] = {
    
    0};
LNode *pHead;

void CreateList(int n);
void Josephus(int m, int n);

int main()
{
    
    
    int m,n;

    cin>>m>>n;
    for(int i = 0;i < n;i++)
    {
    
    
        cin>>a[i];
    }
    CreateList(n);
    Josephus(m,n);
    return 0;
}

void CreateList(int n)
{
    
    
    LNode *pNew;
    LNode *pEnd = (LNode*)malloc(sizeof(LNode));

    for(int i = 0;i < n;i++)
    {
    
    
        pNew = (LNode*)malloc(sizeof(LNode));
        pNew->id = i + 1;
        pNew->password = a[i];

        if(i == 0)
        {
    
    
            pHead = pNew;
        }
        else
        {
    
    
            pEnd->next = pNew;  //表示上一个节点的下一个节点是本节点
        }
        pNew->next = pHead; //循环
        pEnd = pNew;    //end赋为新地址
    }
}

void Josephus(int m,int n)
{
    
    
    LNode *p = pHead;
    LNode *target = pHead;
    int number = 0;
    while(n--)
    {
    
    
        if(m == 1 && p == pHead)//1是特殊情况
        {
    
    
            while(p->next != pHead) //  找到tail
            {
    
    
                p = p->next;
            }
            target = pHead;
            m = target->password;
            number = target->id;
            p->next = pHead->next;
            free(pHead);
            pHead = p->next;
            p = pHead;
        }
        else
        {
    
    
            LNode * q;
            int i = 1;
            while(m != i)
            {
    
    
                q = p;
                p = p->next;
                i++;
            }
            target = p;
            q->next = p->next;
            m = target->password;
            number = target->id;
            free(p);
            p = target->next;   //target的下一个元素继续开始
        }
        cout<<number<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_46052886/article/details/114804889