小猪的数据结构辅助教程——2.6 经典例子:魔术师发牌问题和拉丁方阵问题

小猪的数据结构辅助教程——2.6 经典例子:魔术师发牌问题和拉丁方阵问题

标签(空格分隔): 数据结构


本节引言:

本节继续带来的是循环链表的两个经典例子,分别是魔术师发牌问题和拉丁方阵问题!


1.魔术师发牌问题

问题描述

魔术师利用一副牌中的13张黑桃牌,预先将他们排好后叠放在一起,牌面朝下。对观众说:“我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将牌堆最上面的哪张排数为1,把他翻过来正好是黑桃A,将黑桃A从牌堆抽出放在桌子上,第二次数1、2,将第一张放在牌堆最下面,第二张翻开,正好是黑桃2,也将它抽出放在桌子上。这样依次进行将13将牌全部翻出,准确无误。问牌最开始的顺序是怎样排的。

简单点说:把13张牌按照一定的顺序排好,然后依次取牌,将每次取到的牌放在最下面,情形如下:

数一次,取牌,黑桃1,放牌堆最下面

数两次,取牌,黑桃2,放牌堆最下面

数三次,取牌,黑桃3,放牌堆最下面

数四次,取牌,黑桃4,放牌堆最下面

…直到取到最后的黑桃13(黑桃K),表演结束!

问题思路

这里我们可以用到循环链表,先初始化13个结点,全设置为0,然后开始数数,数到对应的结点,判断是否

为0,为0的话插牌,不为0的话,继续后移!一时半伙也说不清楚,用表格阐述下吧,可能更容易理解

代码实现

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

#define CARD_NUM 13

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;
typedef struct LNode *LinkList; 

//定义一个初始化链表的方法
LinkList ListCreate()
{
    LinkList head = NULL,p,q = head;
    int i;
    for(i = 1;i <= CARD_NUM;i++)
    {
        p = (LinkList)malloc(sizeof(LNode));
        p ->data = 0;
        if(head == NULL)head = p;
        else q ->next = p;
        q = p;
    }
    q ->next = head;
    return head;
} 

//计算发牌顺序(核心)
void deal(LinkList L)
{
    LinkList p;
    int j;
    int countNum = 2;  //记录当前应该到哪张牌
    p = L;
    p ->data = 1;   //第一张牌嘛,肯定是1
    while(1)
    {
        for(j = 0;j <countNum;j++)
        {
            p = p ->next;
            if(p ->data != 0)  //不为0说明这个位置已经有牌了,后移
            {
                p ->next;
                j--;
            }
        }
        if(p->data == 0)  //不为0说明这个位置没牌,那么将牌插入,牌+1
        {
            p ->data = countNum;
            countNum++;
            if(countNum == 14)break;    //13张牌放置完毕,退出循环
        }
    }
} 

int main()
{
    LinkList p = NULL;
    int i;
    p = ListCreate();
    deal(p);
    printf("牌的放置顺序为:\n\n");
    for(i = 0;i < CARD_NUM;i++)
    {
        printf("黑桃%d\t",p ->data);
        p = p ->next;
    }
    printf("\n\n");
    return 0;
}

运行截图


2.拉丁方阵问题

问题描述

拉丁方阵是一种n×n的方阵,方阵中恰有n种不同的元素,每种元素恰有n个,

并且每种元素在一行和一列中恰好出现一次。著名数学家和物理学家欧拉使用拉

丁字母来作为拉丁方阵里元素的符号,拉丁方阵因此而得名。

BB那么久,可能连题目都看不懂,没事,我们列下3 x 3,4 x 4,5 x 5的拉丁方阵给大家体验下

大家就知道了!

拉丁方阵图例子图:

不知道你发现这样一个规律没?

比如3 x 3的拉丁方阵,第一行是1,2,3,第二行好像都向前移了一位,然后第一个元素跑到了最后面…

用循环链表不就刚好么?非常简单,下面撸下代码~

代码实现

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

typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;
typedef struct LNode *LinkList; 

//定义一个初始化链表的方法
LinkList ListCreate(int n)
{
    LinkList head = NULL,p,q = head;
    int i;
    for(i = 1;i <= n;i++)
    {
        p = (LinkList)malloc(sizeof(LNode));
        p ->data = i;
        if(head == NULL)head = p;
        else q ->next = p;
        q = p;
    }
    q ->next = head;
    return head;
} 

int main()
{
    LinkList p,q;
    int i,num = 0;
    printf("请输入您要构建的拉丁方针的规模(比如3*3,输入3即可)\n");
    scanf("%d",&num);
    p = ListCreate(num);
    printf("%d * %d 的拉丁方阵构建完毕,输出结果:\n\n",num,num);
    for(i = 0;i < num;i++)
    {
        q = p;
        while(1)
        {
            printf("%d  ",p ->data);
            p = p ->next;
            if(p == q)break;  //已经走完一轮了
        }
        p = p ->next;
        printf("\n");
    }
    printf("拉丁方阵打印完毕~~\n\n");
    return 0;
}

运行截图

还是蛮简单的,看不懂的话,代码撸一遍,画图,会更加帮助你理解,动手!动手!动手!


3.本节代码下载:

https://github.com/coder-pig/Data-structure-auxiliary-tutorial/blob/master/List/magician.c

https://github.com/coder-pig/Data-structure-auxiliary-tutorial/blob/master/List/lading.c

时间: 2024-10-13 21:56:48

小猪的数据结构辅助教程——2.6 经典例子:魔术师发牌问题和拉丁方阵问题的相关文章

小猪的数据结构辅助教程——2.5 经典例子:约瑟夫问题的解决

小猪的数据结构辅助教程--2.5 经典例子:约瑟夫问题的解决 标签(空格分隔): 数据结构 约瑟夫问题的解析 关于问题的故事背景就不提了,我们直接说这个问题的内容吧: 一堆人,围成一个圈,然后规定一个数N,然后依次报数,当报数到N,这个人自杀,其他人鼓掌!啪啪啪, 接着又从1开始报数,报到N又自杀-以此类推,直到死剩最后一个人,那么游戏结束! 这就是问题,而我们用计算机模拟的话,用户输入:N(参与人数),M(第几个人死),结果返回最后一个人! 类似的问题有跳海问题,猴子选王等,下面我们就以N =

小猪的数据结构辅助教程——3.1 栈与队列中的顺序栈

小猪的数据结构辅助教程--3.1 栈与队列中的顺序栈 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点 1.栈与队列的介绍,栈顶,栈底,入栈,出栈的概念 2.熟悉顺序栈的特点以及存储结构 3.掌握顺序栈的基本操作的实现逻辑 4.掌握顺序栈的经典例子:进制变换的实现逻辑 1.栈与队列的概念: 嗯,本节要进行讲解的就是栈 + 顺序结构 = 顺序栈! 可能大家对栈的概念还是很模糊,我们找个常见的东西来拟物化~ 不知道大家喜欢吃零食不--"桶装薯片"就可以用来演示栈! 生产的时

小猪的数据结构辅助教程——2.1 线性表中的顺序表

小猪的数据结构辅助教程--2.1 线性表中的顺序表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.抽象数据类型(ADT)的概念,三要素:数据,数据元素间的关系和数据的操作 2.线性表的特点:按照一条线排列的数据集合,1对1,除了首元和尾元,其他元素都有直接前驱和直接后继 3.牢记线性表的存储结构,要理解并熟悉12个基本操作的逻辑,最好能徒手撕出代码 4.求并集,顺序表的经典例子,必须掌握! 1.抽象的数据类型 简单点说: 抽象:有点像我们面向对象语言中的类的思想,将事物

小猪的数据结构辅助教程——2.7 线性表中的双向循环链表

小猪的数据结构辅助教程--2.7 线性表中的双向循环链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.了解引入双向循环链表的原因 2.熟悉双向循环链表的特点以及存储结构 3.掌握双向循环链表的一些基本操作的实现逻辑 4.掌握逆序输出双向循环链表元素逻辑 1.双向循环链表的引入 2.双向循环链表的存储结构 双向循环链表的特点: 上面也说了,空间换时间,比起循环链表只是多了一个指向前驱的指针 特点的话: 判断空表:L ->next = L -> prior = L; 存

小猪的数据结构辅助教程——2.4 线性表中的循环链表

小猪的数据结构辅助教程--2.4 线性表中的循环链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.了解单链表存在怎样的缺点,暴露出来的问题 2.知道什么是循环单链表,掌握单链表的特点以及存储结构 3.掌握循环链表的一些基本操作的实现逻辑,最好能手撕代码 1.循环单链表的引入 2.循环链表的特点以及存储结构 循环链表的特点: 上面也说了,比单链表稍微高比格一点的地方就是: 链表最后一个结点的指针域指向了头结点而已,这样形成所谓的环,就是循环单链表了,呵呵! 特点的话有:

小猪的数据结构辅助教程——3.2 栈与队列中的链栈

小猪的数据结构辅助教程--3.2 栈与队列中的链栈 标签(空格分隔): 数据结构 1.本节引言: 嗯,本节没有学习路线图哈,因为栈我们一般都用的是顺序栈,链栈还是顺带提一提吧, 栈因为只是栈顶来做插入和删除操作,所以较好的方法是将栈顶放在单链表的头部,栈顶 指针与单链表的头指针合二为一~所以本节只是讲下链栈的存储结构和基本操作! 2.链栈的存储结构与示意图 存储结构: typedef struct StackNode { SElemType data; //存放的数据 struct StackN

小猪的数据结构辅助教程——1.数据结构与算法绪论

小猪的数据结构辅助教程--1.数据结构与算法绪论 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.了解数据结构的相关概念 2.了解算法的相关概念 3.熟悉时间复杂度的计算 4.了解空间复杂度的概念,闰年表空间换时间的样例~ 1.什么是数据结构? 2.算法的叙述 3.时间复杂度计算的简单演示样例 数据结构预算法--时间复杂度分析实例

小猪的数据结构辅助教程——2.2 线性表中的单链表

小猪的数据结构辅助教程--2.2 线性表中的单链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.理解顺序表以及单链表各自的有点以及缺点! 2.熟悉单链表的形式,对于头指针,头结点,尾结点,数据域和指针域这些名词要知道是什么! 3.熟悉单链表的结点结构 4.区分头指针与头结点! 5.熟悉创建单链表的两种方式:头插法和尾插法 6.了解单链表12个基本操作的逻辑 7.有趣的算法题:查找单链表的中间结点~ 1.单链表的引入(顺序表与单链表的PK) 2.单链表的结构图以及一些名

小猪的数据结构学习笔记(五)

小猪的数据结构学习笔记(五) 线性表之--循环链表                           --转载请注明出处:coder-pig 循环链表知识点归纳: 相关代码实现: ①判断是否为空表: ②单循环链表的存储结构 其实和单链表的结构是一样的! /*定义循环链表的存储结构*/ typedef struct Cir_List { int data; struct Cir_List *next; }Lnode; ③初始化循环单链表 代码如下: //1.循环链表的初始化 //表示一个元素,如