自杀环---约瑟夫环(单链表经典面试题)------>C语言实现

本文介绍了一个经典的数学问题——约瑟夫环,并提供了一种使用C语言链表实现的解决方案。该方案首先构建了一个链表来模拟人员的围坐状态,然后通过循环算法实现了按特定规则淘汰成员直至最后一名成员的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-运行环境:win10,VS2013
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始从1报数,数到M的那个人出列;他的下一个人又从1开始报数,数到M的那个人又出列;依此规律重复下去,直到剩余一个人
这里写图片描述

这里写图片描述

这里写图片描述
这里写图片描述
LinkList.c

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;//定义数据类型
//节点的构造
typedef struct Node
{
    DataType data;
    struct Node*pNext;
}Node,*PNode;
//初始化
void InitLinkList(PNode* pHead)
{
    assert(pHead);//断言
    (*pHead) = NULL;
}
//构造新节点
PNode BuyNode(DataType x)
{
    PNode pCur = (PNode)malloc(sizeof(Node));
    if (NULL == pCur)
        return NULL;
    else
    {
        pCur->data = x;
        pCur->pNext = NULL;
        return pCur;
    }
}
//打印链表
void PrintLinkList(PNode pHead)
{
    assert(pHead);
    if (NULL == pHead)
        printf("NULL");
    else
    {
        while (pHead)
        {
            printf("%d--->", pHead->data);
            pHead = pHead->pNext;
        }
        printf("NULL");
    }
    printf("\n");
}
//尾插
PNode PushBack(PNode* pHead,DataType x)
{
    assert(pHead);
    PNode pTail = NULL;
    PNode pCur = BuyNode(x);//调用BuyNode()函数,对给出的data构造节点
    if (NULL == (*pHead))
    {
        (*pHead) = pCur;
    }
    else
    {
        pTail = (*pHead);
        while (pTail->pNext)
        {
            pTail = pTail->pNext;
        }
        pTail->pNext = pCur;
    }
    return pHead;
}
//约瑟夫环函数
PNode JosephCircle(PNode pHead, size_t M)
{
    PNode pCur = pHead;
    PNode pDel = NULL;
    assert(pHead);
    //如果链表是空链表或者只有一个节点,都返回头指针
    if (NULL == pHead||NULL==pHead->pNext)
        return pHead;
    //给链表构环
    while (pCur->pNext)
    {
        pCur = pCur->pNext;
    }
    pCur->pNext = pHead;
    pCur = pHead;
    //循环删除节点
    while (pCur != pCur->pNext)
    {
        int count = M;//报数为count
        while (--count)
        {
            pCur = pCur->pNext;
        }
        //替换法删除节点(通过删除需要删除节点的下一个节点)
        pDel = pCur->pNext;
        pCur->data = pDel->data;
        pCur->pNext = pDel->pNext;
        free(pDel);
        pDel = NULL;
    }
    //解环
    pCur->pNext = NULL;
    return pCur;
}

test.c

void test()
{
    struct Node* pHead;
    struct Node* p;
    InitLinkList(&pHead);
    PushBack(&pHead, 2);
    PushBack(&pHead, 3);
    PushBack(&pHead, 4);
    PushBack(&pHead, 5);
    PushBack(&pHead, 6);
    PushBack(&pHead, 7);
    PushBack(&pHead, 8);
    PushBack(&pHead, 9);
    PrintLinkList(pHead);//打印链表
    p=JosephCircle(pHead, 3);
    PrintLinkList(p);
}
int main()
{
    test();
    system("pause");
    return 0;
}

运行结果:
这里写图片描述
ps:由此可见,Josephus是多么聪明的一个人啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值