队列,堆栈和结构体举例(C语言)

    自己啃算法书整理了一个同时运用堆栈和队列的代码,对这块内容还比较模糊的可以看看~,以下是代码和注解。(留个赞再走呗!)

//游戏:小哼和小哈玩小猫钓鱼的纸牌游戏。刚开始每人手中有6张牌,打到最后谁的手中还有牌谁就获胜

//提示:小哼和小哈手中的牌用队列表示,桌上的牌用堆栈表示,所有要定义3个结构体,两个队列,一个堆栈

#include <stdio.h>

//队列结构体
struct queue
{
int data[100];
int head;
int tail;
};

//堆栈结构体
struct stack
{
int data[10];
int top;
};

int main()
{
struct queue q1,q2;
struct stack s;
int i,t;
int book[10]={0};//若桌上纸牌1有3张,则book[1]=3;若桌上纸牌5有6张,则book[5]=6

//对队列的head和tail初始化,刚开始队列为空,所以head和tail都是1
q1.head=1;q1.tail=1;//小哼
q2.head=1;q2.tail=1;//小哈

//游戏开始时,桌上没有纸牌
s.top=0;

//给小哼发牌
for (i=1;i<=6;i++)
{
	scanf("%d",&q1.data[q1.tail]);
		q1.tail++;
}
//给小哈发牌
for (i=1;i<=6;i++)
{
	scanf("%d",&q2.data[q2.tail]);
	q2.tail++;

}
//6个数字都进入队列后,tail指向队列最后一个数的后面一位


while(q1.head<q1.tail && q2.head<q2.tail)//当队列不为空的时候执行(即小哼和小哈手中都有牌才能开始游戏)
{
	t=q1.data[q1.head];//将队列的第一个数存放在t中(即将要打出的纸牌上的数字)
	if (book[t]==0) //book[t]=0表示桌上没有和t相同的数
	{
		q1.head++;//将t从q1队列中出队,队列中的下一个数作为head;(即小哼打出了一张牌)
		s.top++;
		s.data[s.top]=t;//将出队的t放进s堆栈中(将小哼打出的牌放到了桌上)
		book[t]=1;//此时桌上的纸牌t的张数为1		
	}
	else 
	{
		//此时小哼可以赢牌
		q1.head++;//队列中的下一个数作为head
		q1.data[q1.tail]=t;//将出队的t重新入队到队列q1的末尾tail处
		q1.tail++;
		while (s.data[s.top]!=t)//此时的top指向堆栈s的最顶端(即桌上的最后一张纸牌),该纸牌和t不相等时执行循环
		{
			book[s.data[s.top]]=0;//s.data[s.top]表示桌上最末端的纸牌上的数字,对它取消标记
			q1.data[q1.tail]=s.data[s.top];//将桌上最末端的纸牌放进q1队列中
			q1.tail++;//tail指向队列q1最后一个数的后面一位
			s.top--;//top往前移(top往下移,保证top永远指向堆栈s的最顶端)
		}
	}


	t=q2.data[q2.head];
	if (book[t]==0) //book=0表示桌上没有和t相同的数
	{
		q2.head++;//将t从q2队列中出队,并且head++;(即小哼打出了一张牌)
		s.top++;
		s.data[s.top]=t;//将出队的t放进s堆栈中(将小哼打出的牌放到了桌上)
		book[t]=1;//此时桌上的纸牌t的张数为1		
	}
	else 
	{
		//此时小哈可以赢牌
		q2.head++;//将t从q2队列中出队
		q2.data[q2.tail]=t;//将出队的t重新入队到队列q2的末尾tail处
		q2.tail++;
		while (s.data[s.top]!=t)//此时的top指向堆栈s的最顶端(即桌上的最后一张纸牌),该纸牌和t不相等时执行循环
		{
			book[s.data[s.top]]=0;//s.data[s.top]表示桌上最末端的纸牌上的数字,对它取消标记
			q2.data[q2.tail]=s.data[s.top];//将桌上最末端的纸牌放进q2队列中
			q2.tail++;//tail指向队列q2最后一个数的后面一位
			s.top--;//top往前移(top往下移,保证top永远指向堆栈s的最顶端)
		}
	}
}

if (q1.head==q1.tail)//表示队列q1为空(即小哼手中的牌已全部打出)
{
	printf("小哈获胜\n");
	printf("小哈手中的牌为:\n");
	for (i=q2.head;i<=q2.tail-1;i++)
	{
		printf("%d ",q2.data[i]);
	}
	

	if (s.top>0)//s.top>0表示桌上还有牌
	{
		printf("桌上剩余的纸牌为:");
		for (i=1;i<=s.top;i++)
		{
			printf("%d ",s.data[i]);
		}
		printf("\n");
	}
	else
		printf("桌上没有纸牌剩余");

}
else
{
	printf("小哼获胜\n");
	printf("小哼手中的牌为:");
	for (i=q1.head;i<=q1.tail-1;i++)
	{
		printf("%d ",q1.data[i]);
	}
	printf("\n");
	
	if (s.top>0)//s.top>0表示桌上还有牌
	{
		printf("桌上剩余的纸牌为:");
		for (i=1;i<=s.top;i++)
		{
			printf("%d ",s.data[i]);
		}
		printf("\n");
	}
	else
		printf("桌上没有纸牌剩余");

}

return 0;

}

测试数据:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值