数据结构-----约瑟夫环(循环链表)

#include <iostream>
#include <stdio.h>

#include <stdlib.h>
using namespace std;
typedef struct node{
    int number;
    struct node *next;
}person;

//创建约瑟夫环循环链表
person* initLink(int n)
{
   person * head=(person*)malloc(sizeof(person));
    head->number=1;
    head->next=NULL;
    person* cyclic=head;
    for(int i=2;i<=n;i++)
    {
        person* body=(person*)malloc(sizeof(person));
        body->number=i;
        body->next=NULL;
        cyclic->next=body;
        cyclic=cyclic->next;
    }

    cyclic->next=head;   //首尾相连
    return head;
}

//从编号K开始数M次,退出
void findAndKillK(person * head,int k,int m){
    printf("11111111");
    person * tail=head;
    //假如删除第一个节点呢?找到链表第一个结点的上一个结点,为删除操作做准备
//    while (tail->next!=head) {
//     tail=tail->next;
//     }
    
    person * p=head;

    //找到编号为 k 的人
    while(p->number!=k)
    {
        tail=p;
        p=p->next;
    }
    //从编号为 k 的人开始,只有符合 p->next==p 时,说明链表中除了 p 结点,所有编号都出列了
    while (p->next!=p)
     {
    
    //找到从 p 报数 1 开始,报 m 的人,并且还要知道数 m-1de 人的位置 tail,方便做删除操作
        for(int i=1;i<m;i++)
        {
            tail=p;
            p=p->next;
        }

        tail->next=p->next;
        printf("出列人的编号为:%d\n",p->number);
        free(p);
        p=tail->next;//继续使用 p 指针指向出列编号的下一个编号,游戏继续
    }
    printf("出列人的编号为:%d\n",p->number);
    free(p);

}

int main() {
    int n;
    int k;
    int m;
    cout<<"输入圆桌上的人数 n:"<<endl;
    cin >> n;
    person* head=initLink(n);
    cout << "从第 k 人开始报数(k>1 且 k<"<< n <<")" << endl;
    cin >> k;
    cout << "数到 m 的人出列:"<<endl;
    cin >> m;
    cout<< "n="<< n<<","<<"k="<< k<<","<<"m="<< m<<endl;
    findAndKillK(head, k, m);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/aa804738534/article/details/113729119