Monkey chooses king (circular singly linked list)

 

#include<stdio.h>
#include<stdlib.h>
struct Node
{
    unsigned long number;//存储某只猴子的编号
    struct Node *next;//指向下一猴子结点的指针
};
struct Node *head;//全局头指针
struct Node *start;//全局指针, 表非空时指向表的第一个结点; 否则指向头结点
struct Node *rear;//全局尾指针, 表非空时指向表的最后一个结点; 否则指向头结点
void create_List()//创建循环链表
{
    head=(struct Node*)malloc(sizeof(struct Node));
    head->number=0;//头结点的数据域存储当前猴子的数量
    head->next=head;//表空
    start=head;
    rear=head;
    return ;
}
void insert_Elem(unsigned long n)//向链表中插入结点
{
    struct Node *p;
    p=(struct Node*)malloc(sizeof(struct Node));
    if(head->number==0)//表空
    {
        start=p;//修改开始元素指针
    }
    //
    p->number=n;//填充数据域
    //
    rear->next=p;//将新申请结点插入表中
    p->next=head;//保持链表的循环性
    rear=p;//尾指针指向新申请结点
    //
    head->number++;//表内猴子数量+1
    return ;
}
void Traversal()//遍历循环链表
{
    struct Node *p=start;
    while(p!=head)
    {
        printf("%ld ", p->number);
        p=p->next;
    }
    putchar('\n');
    return ;
}
//
void f(unsigned long k)//关键算法
{
    if(head->number==0)//空表
    {
        return ;
    }
    struct Node *p=start;
    struct Node *q=head;
    struct Node *s=start->next;
    unsigned long i=1;
    while(head->number>1)//圈中还有猴子
    {
        if(i==k)//找到出圈的猴子
        {
            if(p!=head)
            {
                q->next=s;
                free(p);
                s=s->next;
                p=q->next;
                head->number--;//猴子数量-1
                i=1;
            }
            else//跳过头结点
            {
                p=p->next;
                q=q->next;
                s=s->next;
            }
        }
        else//没找到出圈的猴子
        {
            if(p!=head)
            {
                s=s->next;
                p=p->next;
                q=q->next;
                //三个指针整体后移
                i++;
            }
            else
            {
                s=s->next;
                p=p->next;
                q=q->next;
                //三个指针整体后移
            }
        }
    }
    printf("%ld\n", head->next->number);
    return ;
}
int main()
{
    unsigned long i=1;
    create_List();
    unsigned long num;//猴子的数量
    unsigned long k;//报数值
    scanf("%ld%ld", &num, &k);
    while(i<=num)
    {
        insert_Elem(i);
        i++;
    }//初始化num只猴子
    //Traversal();
    f(k);
    return 0;
}

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_42048463/article/details/114986955