码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构(一)线性表循环链表之约瑟夫环

时间:2018-08-05 17:27:58      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:9.png   size   节点   需要   struct   and   ++   image   src   

(一)前提

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\n", 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\n", L->data); //输出最后一个人 free(L); system("pause"); return 0; }

技术分享图片

 

数据结构(一)线性表循环链表之约瑟夫环

标签:9.png   size   节点   需要   struct   and   ++   image   src   

原文地址:https://www.cnblogs.com/ssyfj/p/9426368.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!