数据结构 C语言 02 -- 单向循环链表 实现 约瑟夫问题

本文介绍了如何使用C语言基于单向循环链表解决约瑟夫问题。问题描述为n个人围成一圈,从第k个开始按m报数,数到m的人被淘汰,直至剩下最后一个人。文中提供了算法实现及运行结果。
摘要由CSDN通过智能技术生成

约瑟夫问题是个有名的问题:n个人围成一圈,从第k个开始报数,报数m个将被杀掉,从下一个开始报数m,最后剩下一个。

运行结果:
在这里插入图片描述

该问题的主要算法func2.c,clinklist.c为单向循环链表的相关操作。

/*
func2.c
*/
#include "func2.h"

void func2(int n,int k, int m)
{
   
    //创建循环链表 表示人群
    CLinkList *head = Create_CLinklist();
    
    //人员加入
    printf("Input %d people ID[SPACE]:\n",n);
    int i,id;
    int tail = CLinklist_Length(head)+1; //初始人数0,tail指向位置1
    
    for(i = 1; i <= n; i++){
   
        scanf("%d",&id);
        CLinklist_Insert_Pos(head,tail,id); //尾插
        tail++;  //尾插标记+1
    }

    //start 指向开始位置结点
    Node *start = head;
    while(k--){
   
        start = start->next;
    }

    //删除头节点
    Node *p = head;
    while(p->next != head){
   //遍历指向尾结点
        p = p->next;
    }
    p->next = head->next;
    free(head);
    
    //开始
    printf("先淘汰的: ");
    int j;
    while(start->next != start){
   //只有一个结点时 退出
        j = m-1;//控制start指向要删除结点的上一个位置
        while(--j) start = start->next;
        
        printf("%d ",start->next->data);//打印出即将删除的结点

        CLinklist_Delete_Add(start);//删除结点 输入前一个结点地址
        start = start->next;//下一次 从下一个结点开始
    }

    //打印出最后活着的
    printf("\n最后活着的: %d\n",start->data);

}
/*
main.c
*/
#include "clinklist.h"

int main()
{
   
    int n; //初始总人数
    int k; //开始位置
    int m; //报数
    
    printf("n-总人数 k-开始位置 m-报数\n");
    printf("Input n k m[SPACE]: ");
    scanf("%d %d %d",&n,&k,&m);

    func2(n,k,m);

    return 0;
}
/*
func2.h
*/
#ifndef __FUNC2__
#define __FUNC2__

void func2(int n,int k, int m);

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值