循环链表解决约瑟夫问题

  训练一下尾插法和循环链表的使用。

//循环链表解决约瑟夫问题
#include <stdio.h>
#include <stdlib.h>
typedef struct CycleLinkList
{
    int data;
    struct CycleLinkList * next;
}cycleLinkList;

cycleLinkList * h, * r, * s;                // 头指针、尾指针
int main()
{
    int i, j;
    int n, num;
    cycleLinkList * L;
    printf("请输入参与约瑟夫环的总人数及淘汰者编号:");
    scanf("%d %d",&n,&num);

    h = (cycleLinkList *)malloc(sizeof(cycleLinkList));
    r = h;
    for(i = 0; i < n; i++)                    // 尾插法建立链表
    {
        s = (cycleLinkList *)malloc(sizeof(cycleLinkList));
        s -> data = i + 1;                    // 为参与人员编号
        r -> next = s;                        // 中间过程分配的空间插到尾指针后面
        r = s;
    }

    r -> next = NULL;
    L = h -> next;
    while(L)
    {
        printf("%d ",L -> data);
        L = L -> next;
    }

    r -> next = h -> next;
    L = h -> next;
    while(L -> next != L)
    {
        for(j = 1; j < num - 1; j++)
        {
            L = L -> next;
        }
        L -> next = L -> next -> next;
        L = L -> next;
    }
    puts("\n最终胜利者:");
    printf("%d\n",L -> data);
    return 0;
}

  运行效果:

  以前不会尾插法的时候,我的循环链表是这样的:

#include <stdio.h>
#include <stdlib.h>

typedef struct CycleLinkList
{
    int data;
    struct CycleLinkList * next;
}cycleLinkList;

cycleLinkList * h, * r, * s;

int main()
{
    int i, j;
    int n, num;
    h = NULL;
    printf("请输入参与约瑟夫环的总人数及淘汰者编号:");
    scanf("%d %d",&n,&num);

    for(i = 0; i < n; i++)
    {
        r = (cycleLinkList *)malloc(sizeof(cycleLinkList));
        if(h == NULL)
            h = r;
        else
            s -> next = r;
        r -> next = NULL;
        r -> data = i + 1;
        s = r;
    }

    r = h;
    while(r)
    {
        printf("%d ",r -> data);
        r = r -> next;
    }
    putchar(‘\n‘);

    r = h;
    while(r -> next != r)
    {
        for(j = 1; j < num - 1; j++)
        {
            r = r -> next;
            if(r -> next == NULL)
                r -> next = h;
        }
        r -> next = r -> next -> next;
        r = r -> next;
    }
    puts("最终胜利者:");
    printf("%d \n",r -> data);
    return 0;
}

  这是我用以前的方法实现的,但有很多问题因为这样的方法会找不到头结点的,因而只有一部分可以成功实现效果:

(一)

(二)

时间: 2024-08-05 15:27:04

循环链表解决约瑟夫问题的相关文章

C++循环链表解决约瑟夫环问题

约瑟夫环问题可以简单的使用数组的方式实现,但是现在我使用循环链表的方法来实现,因为上午看到一道面试题规定使用循环链表解决约瑟夫环问题. 什么是约瑟夫环? “约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列.”(百度百科中的解决办法列出了很多,可以看到循环链表并不是最简单的方法) 这道面试题考察了循环链表的“创建”,

C++ 用循环链表解决约瑟夫环问题

约瑟夫环问题 已知 n 个人(n>=1)围坐一圆桌周围,从 1 开始顺序编号,从序号为 1 的人开始报数,顺时针数到 m 的那个人出列.下一个人又从 1 开始报数,数到m 的那个人又出列.依此规则重复下去,直到所有人全部出列.请问最后一个出列的人的初始编号. 要求 输入人数 n,所报数 m,输出最后一个人的初始编号. 解决思路 首先因为是圆桌问题,使用链表解决的话需要构建循环链表. 接着是出列问题,这里我的设计思路是将指向链表的指针移动到需要出列的人的位置,然后根据正常的链表删除进行操作即可.

用循环链表解决约瑟夫问题

约瑟夫问题描述:从N个人中选出一个领导人,方法如下:所有人排除一个圆圈,按顺序数数,每数到第M的人出局,此时他两边的人 靠拢重新形成圆圈,从已出局人的下一个继续进行.问题是找出哪一个人将会是最后剩下的那个人,甚至我们更希望 知道出局人的顺序. 算法思路:构造一个循环链表来表示排成圆圈的人.每人的链接指向圆圈内他左边(或者右边)的人.圆圈内人第i个人用整数i 表示.首先为1号构造一个节点的循环链表,然后再把2~N号插入到1号节点之后,得到一个1~N的环,并时x指向节点N .然后从1号开始,跳过M-

用循环链表解决约瑟夫环的问题

约瑟夫环问题简介 约瑟夫环问题的原来描述为,设有编号为1,2,--,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,--,如此下去,直到所有人全部出圈为止.当任意给定n和m后,设计算法求n个人出圈的次序.  稍微简化一下. 问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号. 解题思路 将每个人的编号作为结点值,因为报数是循环着来的,故可

用循环链表解决约瑟夫环问题

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列. 下面我们用循环列表模拟这个过程: 1 //节点定义与单链表相同,在此省略 2 //use cyclical linked list to solve josephus problem 3 template <typename Type> class Linked

golang数据结构之用循环链表解决约瑟夫环问题

josephu.go package link import ( "fmt" ) type Kid struct { ID int next *Kid } func AddKid(num int) *Kid { first := &Kid{} cur := &Kid{} if num < 1 { fmt.Println("不合法") return first } for i := 1; i <= num; i++ { kid := &am

C语言用数组解决约瑟夫环问题

       在罗马人占领乔塔帕特后,39 个犹太人与约瑟夫及他的朋友躲到一个洞中,大家决定宁愿自杀也不要被敌人抓到,于是确定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而约瑟夫和他的朋友并不想死去,那么他应该怎样安排他和他的朋友的位置,才能逃脱这场死亡游戏呢?         用C语言解决约瑟夫环问题的最佳方式是采用循环链表,但使用数组同样也可以解决瑟夫环的问题.采用循环链表的方法,以后详述.本节主

javascript中使用循环链表实现约瑟夫环问题

1.问题 2.代码实现 /** * 使用循环链表实现解决约瑟夫环问题 * */ //链表节点 function Node(element){ this.element = element; this.next = null; } //定义链表类 function LList(){ this.head = new Node("head"); this.head.next = this.head; this.find = find; this.insert = insert; this.f

用循环链表求解约瑟夫问题

约瑟夫问题的提法:n个人围成一个圆圈,首先第1个人从1开始,一个人一个人的顺时针报数,报到第m个人,令其出列:然后再从下一个人开始,从1顺时针报数,报到第m个人,再令其出列,…,如此下去,直到圆圈中只剩一个人为止,此人即为优胜者. 例如  n = 8   m = 3 该问题老师让我们在带头节点的单循环链表,不带头节点的单循环链表,双向循环链表,静态循环链表中四选其一实现,我看到问题后第一反应选了带头节点单循环链表,以为这样可以统一空表和非空表的操作,事实上在这个问题中并不需要考虑这些,不过好在四