当前位置:C++技术网 > 资讯 > 有趣的数据结构的小程序——魔术师发牌问题

有趣的数据结构的小程序——魔术师发牌问题

更新时间:2015-12-13 20:08:03浏览次数:1+次

简单点说:把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;
}