zoukankan      html  css  js  c++  java
  • 数据结构(一)线性表循环链表之约瑟夫环

    (一)前提

    41个人报数,1-3,当谁报数为3,谁就去嗝屁。现在获取他们嗝屁的顺序

    (二)实现结构

    顺序:3->1->5->2->4 

    (三)代码实现

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    typedef int ElemType;
    typedef int Status;
    
    typedef struct Node
    {
        ElemType data;
        struct Node* next;
    }Node;
    
    typedef struct Node* CLinkList;
    
    //四个基本操作,初始,清空,判断是否为空,获取长度
    Status InitList(CLinkList* L, int n);
    
    //指定开始位置来打印数据
    void PrintListByIndex(CLinkList rear, int index);
    //用来打印链表
    void PrintList(CLinkList rear);
    老方法声明函数,结构体等
    int main()
    {
        CLinkList L = NULL;
        CLinkList p;
        ElemType e;
        int n = 41;
        int m = 3;
        int i;
    
        InitList(&L,n);        //现在L指向第一个结点
        PrintList(L);
        while (L!=L->next)    //判断头尾指针是否指向相同,相同则元素都不存在
        {
            for (i = 1; i < m-1; i++)
                L = L->next;    //找到要删除的那个结点的前一个
            printf("%d->", L->next->data);    //获取被杀死的人的数据
            p = L->next;    //获取被杀死的人
            L->next = p->next;
            free(p);
    
            L = L->next;//指向新的下一个元素
        }
    
        printf("%d", L->data);    //输出最后一个
        free(L);
    
        system("pause");
        return 0;
    }
    
    
    //四个基本操作,初始,清空,判断是否为空,获取长度
    //初始化不带头结点的链表
    Status InitList(CLinkList* L,int n)
    {
        CLinkList rear, q;    //rear是尾结点
        ElemType item;
        rear = q = NULL;
        srand(time(0));
    
        for (int i = 0; i < n;i++)
        {
            item = rand() % 100;
            if (*L==NULL)
            {
                *L = (CLinkList)malloc(sizeof(Node));
                if (!(*L))
                    return ERROR;
                (*L)->data = item;
                (*L)->next = *L;    //自己指向自己
                rear = *L;    //设置尾指针位置
            }
            else
            {
                //生成新的节点,根据尾指针添加节点,并实时更新尾指针。注意这里数据插入是尾插法
                q = (CLinkList)malloc(sizeof(Node));
                q->data = item;
                q->next = rear->next;
                rear->next = q;
                rear = q;
            }
        }
        return OK;
    }
    //用来打印链表
    void PrintList(CLinkList L)    
    {
        CLinkList q = L;    //获取头指针
        while (q->next != L)
        {
            printf("%d ", q->data);
            q = q->next;
        }
        printf("%d
    ", q->data);
    }
    老方法打印链表PrintList

    (四)扩展提升

    1-N个人,按顺时针一圈,每个人手中有一个密码(一个正整数),
    我们(裁判)定义第一个开始值为M,从第一个人开始自1开始报数,直到报数为M,那么这个人就退出,将他手中的密码值作为新的开始值,
    一直循环直到所有的人都退出

    情景演示 

    修改代码

    int main()
    {
        CLinkList L = NULL;
        CLinkList p;
        ElemType e;
        int n = 19;
        int m;
        int i;
    
        InitList(&L, n);        //现在L指向第一个结点
        PrintList(L);
    
        scanf("%d", &m);    //初始密码值我们输入
        m--;    //下面while循环都是由前一结点开始计算距离的,而我们这里是从第一个结点直接开始的,需要找到他的前一个节点,或者将走的步数减一即可
        while (L != L->next)    //判断头尾指针是否指向相同,相同则元素都不存在
        {
            for (i = 1; i <= m - 1; i++)
                L = L->next;    //找到要退出的那个人的前一个人
            printf("%d->", L->next->data);    //获取将要退出的人的密码
            p = L->next;    //获取即将退出的人
            L->next = p->next;
            m = p->data;    //更新密码值
            free(p);  
         //每次返回的都是退出结点的前一个节点,方便计算当密码为1的情况(重点)
    } printf(
    "%d ", L->data); //输出最后一个人 free(L); system("pause"); return 0; }

  • 相关阅读:
    git
    java网络
    配置本地git服务器(gitblit win7)
    atom 插件安装【转载】
    javaIo
    如何在eclipse中设置断点并调试程序
    如何将工程推到github上
    git操作记录
    编码
    node升级7.0以上版本使用gulp时报错
  • 原文地址:https://www.cnblogs.com/ssyfj/p/9426368.html
Copyright © 2011-2022 走看看