从例题看数据结构队列和栈

喜欢而已 提交于 2020-02-25 20:01:51

今天是周一,周末周六大了两天绿盟杯,被各种大佬暴虐,于是身为菜鸡的我就决定闭关,好了话不多说,今天记录下我看数据结构时的思考和转载的啊哈算法书一些知识。

        首先,开篇是这样描述的:星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓
  鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的
  第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌
  的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人 手中的牌全部出完时,游戏结束,对手获胜。 假如游戏开始时,小哼手中有 6张牌,顺序为 2 4 1 2 5 6,小哈手中也有 6张牌,顺序 为 3 1 3 5 6 4,终谁会获胜呢?现在你可以拿出纸牌来试一试。接下来请你写一个程序来 自动判断谁将获胜。这里我们做一个约定,小哼和小哈手中牌的牌面只有 1~9。

         在这道题目中,我们首先考虑的事扑克牌的存放的问题,这可以用数组完成,接下来我们考虑桌面牌的存放,也是可以用数组表示,但是数组长度怎么设置呢,开小了,会导致越界问题;开大了,又会导致浪费;由于牌又有9张不同的,我们考虑设置成10,好吧这些貌似有点low,我们直接进一步分析,首先设置队列如下:

struct duilie{
int data[1000];
int head;
int tail;
};

接下来设置栈来存储桌上的牌,由于只有九张不同的牌面,我们设置数组长度为10

struct stack{
int  data[10];  //九张牌面
int  top;
};

下面就是队列和栈的初始化

struct duilie p1;
struct duilie p2;      //设置两个变量来存储两人的牌
struct stack s;
p1.head=1;
p1.tail=1;
p2.head=1;
p2.tail=1;         //队列的初始化
s.top=0;         //栈的初始化

我们接下来进行读取牌,每次读入一张牌,然后储存到队列中

for(i=1;i<=6;i++)
{
    scanf("%d",&p1.data[p1.tail]);
    p1.tail++; //读取到队列后,队尾递增
}
for(i=1;i<=6;i++)
{
    scanf("%d",&p2.data[p2.tail]);
    p2.tail++;
}

然后是出牌处理

a=p1.data[p1.head]     //第一个人首先出牌
//打出的牌我们首先放到桌面上,与桌子上的牌进行比较
flag=0
for(i=1;i<=top;i++)
{
  if(a==s[i]){flag=1;break;}
}
//flag=0表明桌面上没有出的牌,牌需要留在桌面
if(flag==0)
{
p1.head++;    //出牌,队列下标增加
s.top++;
s.data[s.top]=a;     //没有相同牌,进行入栈,即放在桌子上
}
//flag=1说明有牌,可以赢牌
if(flag==1)
{
   p1.head++;        //出牌,队列下标增加
   p1.data[p1.tail]=a;
   p1.tail++;         //赢牌,把刚才的牌放到队尾
   while(s.data[s.top]!=a)
   {
      p1.data[p1.tail]=s.data[s.top];
      p1.tail++;
      s.top--;       //把桌面可以赢得牌依次放到栈尾
    }
}

接下来,我们就是判断胜利的过程了;

while(p1.head<p1.tail&&p2.head<p2.tail)
//当队列非空进行循环
if(p2.head==p2.tail)
{
    printf("小哼胜利\n");
    printf("小哼的牌:");
    for(i=p1.head;i<=p1.tail;i++)
       printf("%d",p1.data[i]);
    if(s.top>0)
     {
          printf("桌上的牌是:");
          for(i=1;i<=s.top;i++)
              printf("%d",s.data[i]);
     }
     else
        printf("桌上没牌了");
}

上面是就是这个程序的分析了,由于第二个人获胜的代码相同与第一个人,我这里直接省略了部分代码;下面贴出完整代码

#include<stdio.h>
struct duilie
{
    int data[1000];
    int head;
    int tail;
};
struct stack
{
    int  data[10];  //九张牌面
    int  top;
};
int main()
{
    struct duilie p1,p2;
    struct stack s;
    int pai[10];
    int i,a;
    p1.head=1;
    p1.tail=1;
    p2.head=1;
    p2.tail=1;         //队列的初始化
    s.top=0;         //栈的初始化
    for(i=1;i<=9;i++)
         pai[i]=0; //标记在桌上的牌
    for(i=1;i<=6;i++)
    {
        scanf("%d",&p1.data[p1.tail]);
        p1.tail++; //读取到队列后,队尾递增
    }
    for(i=1;i<=6;i++)
    {
        scanf("%d",&p2.data[p2.tail]);
        p2.tail++;
    }
    while(p1.head<p1.tail && p2.head<p2.tail)
    {
     a=p1.data[p1.head] ;    //第一个人首先出牌
    //打出的牌我们首先放到桌面上,与桌子上的牌进行比较
    if(pai[a]==0)
    {
    p1.head++;    //出牌,队列下标增加
    s.top++;
    s.data[s.top]=a;     //没有相同牌,进行入栈,即放在桌子上
    pai[a]=1;
    }
    //flag=1说明有牌,可以赢牌
    else
    {
       p1.head++;        //出牌,队列下标增加
       p1.data[p1.tail]=a;
       p1.tail++;         //赢牌,把刚才的牌放到队尾
       while(s.data[s.top]!=a)
       {
          pai[s.data[s.top]]=0;
          p1.data[p1.tail]=s.data[s.top];
          p1.tail++;
          s.top--;       //把桌面可以赢得牌依次放到栈尾
        }
    }

    a=p2.data[p2.head] ;    //第一个人出牌
    //打出的牌我们首先放到桌面上,与桌子上的牌进行比较
    if(pai[a]==0)
    {
    p2.head++;    //出牌,队列下标增加
    s.top++;
    s.data[s.top]=a;     //没有相同牌,进行入栈,即放在桌子上
    pai[a]=1;
    }
    else
    {
       p2.head++;        //出牌,队列下标增加
       p2.data[p2.tail]=a;
       p2.tail++;         //赢牌,把刚才的牌放到队尾
       while(s.data[s.top]!=a)
       {
          pai[s.data[s.top]]=0;
          p2.data[p2.tail]=s.data[s.top];
          p2.tail++;
          s.top--;       //把桌面可以赢得牌依次放到栈尾
        }
    }
    }
    if(p2.head==p2.tail)
    {
        printf("小a胜利\n");
        printf("小a的牌:\n");
        for(i=p1.head;i<=p1.tail-1;i++)
           printf("%d ",p1.data[i]);
           printf("\n");
        if(s.top>0)
         {
              printf("桌上的牌是:\n");
              for(i=1;i<=s.top;i++)
                  printf("%d ",s.data[i]);
                  printf("\n");
         }
         else
            printf("桌上没牌了\n");
    }
    else
    {
        printf("小b胜利\n");
        printf("小b哼的牌:\n");
        for(i=p2.head;i<=p2.tail-1;i++)
           printf("%d ",p2.data[i]);
           printf("\n");
        if(s.top>0)
         {
              printf("桌上的牌是:\n");
              for(i=1;i<=s.top;i++)
                  printf("%d ",s.data[i]);
              printf("\n");
         }
         else
            printf("桌上没牌了\n");
    }
return 0;
}

最后在我调试这段代码时报错pai[a] CXX0030: Error: expression cannot be evaluated,审计了半天,发现我在拷贝重复代码时间出错p2.data[p1.tail]=s.data[s.top];忘了更改。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!