约瑟夫环的两种实现

记得大一学数据结构的时候用节点构成了一个循环链做过这个题,前几天偶然想到,为什么不用数组来做呢?


用循环链做的


/*
 **********************************************************
 * 解法
 *
 * 使用一个循环链,其中包含两个元素,一个为指向下一个人的
 * 节点,一个为是否出列的标记
 *
 **********************************************************
 */
#include <stdio.h>
#define M 30  //假设有30个人围成一个圈
#define N 13  //出列13个
#define L 9       //第9个人出列
 
struct node
    {
        int nextp; //指向下一个节点
        int in_out;        //是否出列的标志
    } link[M+1];   //M个人的数组,下标0未曾使用
 
main (void)
{
    int i, j, k; //作为计数器
 
    printf ("The circle is: + mean in; - mean out \n");
 
    for (i = 1; i < M+1; i++)
    {
        link[i].nextp = i + 1;  //指向下一个节点
        link[i].in_out = 1;       //标志为1,表示都尚未出列
    }
 
    link[30].nextp = 1;       //最后一个指向第一个节点,形成一个循环链
 
    j = 30;       //从指向第一个节点的位置开始计数
 
    for (i = 0; i < N; i++)       //i:出列人数的计数器
    {
        for (k = 0; ;)  //k:出列人的计数器
        {
            if (k < L)       
            {
                j = link[j].nextp;        //修改指针,继续计数
                k += link[j].in_out;  //遍历查找出列的人。因为已出列的标记为零,所以可循环查找
            }
            else
                break;
        }
 
        link[j].in_out = 0;       //将出列的人标记为0
    }
 
    printf ("The result is:");
    for (i = 0; i < M; i++)   //输出结果
    {
        printf (" %c ", link[i+1].in_out ? '+': '-');
    }  
    printf ("\n");
 
    return 0;
}


运行之后



用数组做的感觉就清晰了很多


#include<stdio.h>
 
#define M 30  //假设有30个人围成一个圈
#define N 13  //出列13个
#define L 9       //第9个人出列
 
int main (void)
{
    int i, j, k,num,t;   //作为计数器
    int circus[30];
 
    printf ("The circle is: + mean in; - mean out \n");
 
    for (i = 0; i < M; i++)
        circus[i]=1;
 
    k=-1;
    for (i = 0; i < N; i++)       //i:出列人数的计数器
    {
        num=0;
        while(num<L)
        {
            k++;
            num+=circus[k%M];      
        }
        circus[k%M]=0;
    }
 
    printf ("The result is:");
    for (i = 0; i < M; i++)   //输出结果
    {
        printf (" %c ", circus[i] ? '+': '-');
    }  
    printf ("\n");
 
    return 0;
}



运行之后




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值