zoukankan      html  css  js  c++  java
  • 约瑟夫环(改进1.0)

    给定数据版

    //使用循环链表来解决约瑟夫环问题
    //需要对链表实现的功能:
    //1. 初始化链表节点值
    //2. 删掉对应元素
    //3. 返回对应值和序号
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define NUM 7
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    #define OVERFLOW -2
    
    typedef int Status;
    
    typedef struct LinkNode{
        int number;// 序号
        int data;// 对应的步进
        struct LinkNode* next;// 指向下一个节点的指针
    }LinkNode, *LinkList;// 指向结构体的指针
    
    int members[NUM] = { 3, 8, 1, 22, 4, 9, 15 };
    
    // 设立尾指针的单循环链表
    Status ListInit_CL(LinkList &L)
    {
        LinkList l = (LinkList)malloc(sizeof(struct LinkNode));
        if (!l)
            exit(OVERFLOW);
    
        L->next = l;// 用l来处理L后面的链表节点
        int index;
        for (index = 0; index < NUM-1; index++)// 循环赋值
        {
            l->data = members[index];
            l->number = index + 1;// 第几个人
    
            LinkList q = (LinkList)malloc(sizeof(struct LinkNode));// 临时存储
            if (!q) // 分配失败
                return OVERFLOW;
    
            l->next = q;
            l = q;// 移位,当在最后一次的循环中,l所在是空的
            q = NULL;
            free(q);
        }
    
        l->data = members[index];
        l->number = index + 1;
        l->next = L->next;
    
        return OK;
    }
    
    // 删除第i个元素,并由number,data返回其序号和值
    Status ListDelete_CL(LinkList &L, int i, int &number, int &data)
    {
        LinkList q;
    
        int j;
        for (j = 0; j < i - 1; j++)// 移动i-1次,寻找后面第i-1个结点
            L = L->next;
    
        q = L->next;// q指向待删除结点
        L->next = q->next;// L->next指向被删除节点的下一个,后面的计数就是从L现在往后第i个了
    
        //返回被删除节点序号与值
        data = q->data;
        number = q->number;
        free(q);
        return OK;
    }
    
    
    //将原本的第一个节点,置空,用来放置最初始的密码,从第二个节点开始为个人赋值
    //***这样实现所有人都可以用相同的规律排除。***
    //这样会不会使得密码为1的?不会。因为是用一个与原本第一个一样的节点,等价于原本的第一个人的报数。
    //***重点在让指针循环是指向L->next***
    int main()
    {   
        // 让L单独做一个人,后面跟的才是最终循环的人。真正的数据从L->next开始。让他和第一个人数据相同。
        LinkList L = (LinkList)malloc(sizeof(struct LinkNode));
        if (!ListInit_CL(L))
            return ERROR;
    
        int get_data;
        printf("请输入你想要的数字:
    ");
        scanf("%d", &get_data);
    
        int index, get_number = 0;
        for (index = 0; index < NUM - 1; index++)// 只删除n-2个,除了前面删除的一个,最后剩下的就是没有删除的。
        {
            ListDelete_CL(L, get_data, get_number, get_data);
            printf("第%d位被剔除,他的信息是%d
    ", get_number, get_data);
        }
        printf("第%d位被剩下
    ", L->number);
        return OK;
    }
    
    

    随机数版本

    //使用循环链表来解决约瑟夫环问题
    //需要对链表实现的功能:
    //1. 初始化链表节点值
    //2. 删掉对应元素
    //3. 返回对应值和序号
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    #define OVERFLOW -2
    
    typedef int Status;
    
    typedef struct LinkNode{
        int number;// 序号
        struct LinkNode* next;// 指向下一个节点的指针
    }LinkNode, *LinkList;// 指向结构体的指针
    
    // 设立尾指针的单循环链表
    Status ListInit_CL(LinkList &L, int given_people)
    {
        LinkList l = (LinkList)malloc(sizeof(struct LinkNode));
        if (!l)
            exit(OVERFLOW);
    
        L->next = l;// L就当作首,方便最后传出时,L没有变化
    
        int index;
        for (index = 0; index < given_people-1; index++)// 循环赋值
        {
            l->number = index + 1;
    
            LinkList q = (LinkList)malloc(sizeof(struct LinkNode));// 临时存储
            if (!q) // 分配失败
                return OVERFLOW;
    
            l->next = q;
            l = q;// 移位,当在最后一次的循环中,l所在是空的
            q = NULL;
            free(q);
        }
    
        l->number = index + 1;
        l->next = L->next;
    
        return OK;
    }
    
    // 删除第i个元素,并由number返回其序号
    Status ListDelete_CL(LinkList &L, int i, int &number)
    {
        LinkList q;
    
        int j;
        for (j = 0; j < i - 1; j++)// 移动i-1次,寻找后面第i-1个结点
            L = L->next;
    
        q = L->next;// q指向待删除结点
        L->next = q->next;// L->next指向被删除节点的下一个,后面的计数就是从L现在往后第i个了
    
        //返回被删除节点序号
        number = q->number;
        free(q);// 释放待删除结点
    
        return OK;
    }
    
    //将原本的第一个节点,置空,用来放置最初始的密码,从第二个节点开始为个人赋值
    //***这样实现所有人都可以用相同的规律排除。***
    //这样会不会使得密码为1的?不会。因为是用一个与原本第一个一样的节点,等价于原本的第一个人的报数。
    //***重点在让指针循环是指向L->next***
    int main()
    {
        int i, get_number, given_people, given_maxnum;
        printf("请输入人数n,报数上限m
    ");
        scanf("%d %d", &given_people, &given_maxnum);
        if (given_people <= 0 || given_maxnum <= 0)
            return ERROR;
    
        LinkList L = (LinkList)malloc(sizeof(struct LinkNode));
        if (!ListInit_CL(L, given_people))
            return ERROR;
    
        srand((unsigned)time(NULL));
        int rand_number;
        int index;
        for (index = 0; index < given_people - 1; index++)// 只删除n-1个,最后剩下的就是没有删除的。
        {
            ListDelete_CL(L, rand_number = (rand() % given_maxnum) + 1, get_number);
            printf("第%d位被剔除,对应的随机数是%d
    ", get_number, rand_number);
        }
        printf("第%d位被剩下
    ", L->number);
    
        return OK;
    }
    
  • 相关阅读:
    todo---HttpClient,httpUrlConnection
    todo---callback
    todo-braintree-java
    todo--com.paypal.sdk
    todo--OkHttp基本使用
    @RequestBody 和@ResponseBody 注解详解
    常用Jar包下载
    SpringMVC 使用JSR-303进行校验 @Valid
    SpringMVC 之 表单标签
    SpringMVC 自定义类型转换器
  • 原文地址:https://www.cnblogs.com/lart/p/6596250.html
Copyright © 2011-2022 走看看