C语言用循环单链表实现约瑟夫环

用循环单链表实现约瑟夫环(c语言),供大家参考,具体内容如下

源代码如下,采用Dev编译通过,成功运行,默认数到三出局。

主函数:

main.c文件

#include <stdio.h>
#include "head.h"
#include "1.h"

int main()
{
    Linklist L;
    int n;
    printf("请输入约瑟夫环中的人数:");
    scanf("%d",&n);
    Createlist(L,n);
    printf("创建的约瑟夫环为:\n");
    Listtrave(L,n);
    printf("依次出局的结果为:\n");
    Solution(L,n);
    return 0;
}

head.h文件:

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

typedef int Elemtype;
typedef struct LNode{
    Elemtype data;
    struct LNode *next;
}LNode,*Linklist;

void Createlist(Linklist &L,int n)
{
    Linklist p,tail;
    L = (Linklist)malloc(sizeof(LNode));
    L->next = L;//先使其循环
    p = L;
    p->data = 1;//创建首节点之后就先给首节点赋值,使得后面节点赋值的操作能够循环
    tail = L;
    for(int i = 2;i <= n;i++)
    {
        p = (Linklist)malloc(sizeof(LNode));
        p->data = i;
        p->next = L;
        tail->next = p;
        tail = p;
    }
    printf("已生成一个长度为%d的约瑟夫环!\n",n);
}
void Listtrave(Linklist L,int n)//遍历函数
{
    Linklist p;
    p = L;
    for(int i = 1;i <= n;i++)
    {
        printf("%3d",p->data);
        p = p->next;
    }
    printf("\n");
}
int Solution(Linklist L,int n)
{
    Linklist p,s;
    p = L,s = L;
    int count = 1;
    while(L)
    {
        if(count != 3)
        {
            count++;p = p->next;//进行不等于3时的移位
        }
        else
        {
            Linklist q;
            q = p;//用q保存p所指的位置,方便进行节点的删除
            if(s->next->data == s->data)//当只有一个元素的时候
            {
                printf("%3d\n",s->data);
                free(s);
                return OK;
            }
            else//当有两个及两个以上的元素的时候
            {
                count = 1;//先将count重置为1
                printf("%3d",p->data);//再打印出出局的值
                while(s->next != p)
                {
                    s = s->next;//将s移位到p的前驱节点处
                }
                p = p->next;//使p指向自己的下一个节点
                s->next = p;//进行删除
                free(q);
            }
        }
    }
}

1.h文件:

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 约瑟夫环问题(数组法)c语言实现

    问题说明这个问题是以弗拉维奥·约瑟夫斯命名的,它是1世纪的一名犹太历史学家.他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中.他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁.约瑟夫斯和另外一个人是最后两个留下的人.约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀.约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个机智的约瑟夫! 有N个编号为1~N的人围成一圈,现在每隔两个人(比如:1.4 之间隔了2.3)就将一个人淘汰出去,问最后剩下的是编号为几的人? 算法代

  • C语言之单链表的插入、删除与查找

    单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.要实现对单链表中节点的插入.删除与查找的功能,就要先进行的单链表的初始化.创建和遍历,进而实现各功能,以下是对单链表节点的插入.删除.查找功能的具体实现: #include<stdio.h> #include<stdlib.h> #include<string.h> typedef int ElemType; /** *链表通用类型 *ElemType 代表自定义的数据类型 *struct

  • 详解约瑟夫环问题及其相关的C语言算法实现

    约瑟夫环问题 N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的人再从1.2.3开始报数,报p的人再退出圈外,以此类推.   请按退出顺序输出每个退出人的原序号 算法思想 用数学归纳法递推. 无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),若nm非常大,无法在短时间内计算出结果.我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程.因此如果要追求效率,就要打破常规,实

  • 用C语言实现单链表的各种操作(一)

    最近,从新复习了一下数据结构中比较重要的几个部分,现在把自己的成果记录下来,主要就是仿照严蔚敏的<数据结构>(C 语言版),中的例子和后面的习题进行改编的.首先,是单链表的各种实现,其中,包含了一些常考的知识点.例如,单链表的逆置,单链表的合并,找到单链表的中间节点等的算法实现.下面这个是单链表的结构体的定义: 复制代码 代码如下: typedef struct LNode{ ElemType data; struct LNode *next;}LinkList; 下面的基本的单链表的操作:其

  • 利用简洁的C语言代码解决跳台阶问题与约瑟夫环问题

    跳台阶问题 题目: 一个台阶总共有 n 级,如果一次可以跳 1 级,也可以跳 2 级. 求总共有多少总跳法,并分析算法的时间复杂度. 分析: 也是比较基础的题目,通过递归可以方便的求解 代码实现如下(GCC编译通过): #include "stdio.h" #include "stdlib.h" int function(int n); int main(void) { int tmp; tmp = function(5); printf("%3d\n&q

  • C语言实现学生信息管理系统(单链表)

    本文实例为大家分享了C语言实现学生信息管理系统的具体代码,供大家参考,具体内容如下 /*copyright(c)2016.烟台大学计算机学院 * All rights reserved, * 文件名称:text.Cpp * 作者:吴敬超 * 完成日期:2016年7月1日 * 版本号:codeblock * * 问题描述: 学生信息管理系统 * 输入描述: * 程序输出: 输出结果 */ #include <stdio.h> #include <stdlib.h> #include

  • C语言基于循环链表解决约瑟夫环问题的方法示例

    本文实例讲述了C语言基于循环链表解决约瑟夫环问题的方法.分享给大家供大家参考,具体如下: 概述: 约瑟夫环问题,是一个经典的循环链表问题,题意是:已知 n 个人(以编号1,2,3,-,n分别表示)围坐在一张圆桌周围,从编号为 k 的人开始顺时针报数,数到 m 的那个人出列:他的下一个人又从 1 还是顺时针开始报数,数到 m 的那个人又出列:依次重复下去,要求找到最后出列的那个人. 例如有 5 个人,要求从编号为 3 的人开始,数到 2 的那个人出列: 出列顺序依次为: 编号为 3 的人开始数 1

  • C语言创建和操作单链表数据结构的实例教程

    1,为什么要用到链表 数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性.但数组也同样存在一些弊病.如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要3 0个大小的数组,有时需要5 0个数组的大小,难于统一.我们只能够根据可能的最大需求来定义数组,常常会造成一定存储空间的浪费. 我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要.链表就是我们需要的动态数组.它是在程序的执行过程中根据需要有数据存储就向系统要求

  • C语言实现单链表逆序与逆序输出实例

    单链表的逆序输出分为两种情况,一种是只逆序输出,实际上不逆序:另一种是把链表逆序.本文就分别实例讲述一下两种方法.具体如下: 1.逆序输出 实例代码如下: #include<iostream> #include<stack> #include<assert.h> using namespace std; typedef struct node{ int data; node * next; }node; //尾部添加 node * add(int n, node * h

  • C语言约瑟夫环的实现

    C语言约瑟夫环的实现 一.典故: 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是商量了一个自杀方式: 41个人排成一个圆圈,由第1个人 开始报数,每数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而Josephus 和他的朋友并不想遵从,Josephus要 他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死

随机推荐