栈和队列的综合应用-钓鱼

这篇具有很好参考价值的文章主要介绍了栈和队列的综合应用-钓鱼。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第1关:纸牌游戏-钓鱼

任务描述

本关任务:给定任意6张牌给甲、乙,设计一个程序判定“纸牌游戏-钓鱼”的胜者。

测试说明

平台会对你编写的代码进行测试:

测试输入:
2 4 1 2 5 6
3 1 3 5 6 4
预期输出:
甲:4,1,2,5,6,
乙:1,3,5,6,4,
栈:2,3,
甲:1,2,5,6,
乙:3,5,6,4,
栈:2,3,4,1,
甲:6,1,1,2,4,3,2,
乙:5,6,4,
栈:5,3,
甲:1,2,4,3,2,
乙:4,5,6,3,5,
栈:6,1,
甲:2,4,3,2,1,4,1,
乙:5,6,3,5,
栈:6,
甲:4,3,2,1,4,1,
乙:6,3,5,
栈:6,2,5,
甲:2,1,4,1,3,3,
乙:5,6,4,5,2,6,
栈:
甲:1,4,1,3,3,
乙:6,4,5,2,6,
栈:2,5,
甲:4,1,3,3,
乙:4,5,2,6,
栈:2,5,1,6,
甲:3,3,
乙:4,4,5,6,1,5,2,2,
栈:6,1,
甲:3,
乙:4,5,6,1,5,2,2,
栈:6,1,4,3,
甲:
乙:6,1,5,2,2,4,3,4,
栈:6,1,5,3,
甲:
乙:6,1,5,2,2,4,3,4,
栈:6,1,5,3,
乙获胜

输入说明
第一行输入甲手中的6张牌;
第二行输入乙手中的6张牌。

输出说明
甲先出牌,如果发现桌面上有跟刚才打出的牌的数字相同的牌,则把从相同的那张牌开始的全部牌按次序放在自己手里的牌的末尾,再继续出牌,当桌面上没有跟刚才打出的牌的数字相同的牌时,分三行输出甲手里的牌,乙手里的牌,桌上的牌;同理,轮到乙出牌后,分三行输出甲手里的牌,乙手里的牌,桌上的牌,直到有一方获胜。

代码如下

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

typedef  int  SElemType;
typedef  int  QElemType;

# include "sqstack.h"
# include "sqqueue.h"

void output(QElemType s);
void input(QElemType &s);
void outputS(SElemType s);
void inputS(SElemType &s);
int comp(SElemType a, SElemType b);
int LocateElem_Sq(SqStack L, SElemType e, int (*compare)(SElemType, SElemType)) ;

int  main()
{
	SqQueue  q1,q2;            //定义二个队列,代表甲、乙手中的牌
	SqStack  s;                //定义一个栈,代表桌面上的牌
	int i,t,x,n;
	InitQueue(q1);
	InitQueue(q2);
	InitStack(s);	
	for(i=1;i<=6;i++)
	{
		scanf("%d",&t);
    	EnQueue(q1,t);
	}
	for(i=1;i<=6;i++)
	{
		scanf("%d",&t);
		EnQueue(q2,t);
	}
   // 请在这里补充代码,完成本关任务
   /********** Begin **********/ 
	QElemType e,e1,e2;
	int i1,i2,*ix;
	while(!QueueEmpty(q1)&&!QueueEmpty(q2)){
		DeQueue(q1,e1);
		i1=LocateElem_Sq(s,e1,comp);
		Push(s,e1);
		while(i1>=0){
			ix=s.base+i1;
			while(ix<s.top){
				Pop(s,e);
				EnQueue(q1,e);
			}
			DeQueue(q1,e1);
			i1=LocateElem_Sq(s,e1,comp);
			Push(s,e1);
		}
		printf("甲:");
		QueueTraverse(q1,outputS);

		DeQueue(q2,e2);
		i2=LocateElem_Sq(s,e2,comp);
		Push(s,e2);
		while(i2>=0){
			ix=s.base+i2;
			while(ix<s.top){
				Pop(s,e);
				EnQueue(q2,e);
			}
			DeQueue(q2,e2);
			i2=LocateElem_Sq(s,e2,comp);
			Push(s,e2);
		}
		printf("乙:");
		QueueTraverse(q2,outputS);
		printf("栈:");
		StackTraverse(s,outputS);
	}
	if(QueueEmpty(q1))
		printf("乙获胜");
	else
		printf("甲获胜");
	/********** End **********/	
    return 0;
}

int LocateElem_Sq(SqStack L, SElemType e, int (*compare)(SElemType, SElemType)) 
{  
  // 在顺序栈L中查找第1个值与e满足compare()的元素的位序。
  // 若找到,则返回其在L中的位序,否则返回0。
  int i;
  SElemType *p;
  i = 0;        // i的初值为第1个元素的位序
  p = L.base;   // p的初值为第1个元素的存储位置
  int length = L.top-L.base;
  while (i <length && !(*compare)(*p++, e)) 
    ++i;
  if (i < length) 
	  return i;
  else 
	  return -1;
} // LocateElem_Sq

void output(QElemType s)
{
	printf("%d,",s);	   
}

void input(QElemType &s)
{ 	
	scanf("%d",&s);	
}
void outputS(SElemType s)
{
	printf("%d,",s);	   
}

void inputS(SElemType &s)
{ 	
	scanf("%d",&s);	
}
int comp(SElemType a, SElemType b)
{
	if(a>b)
		return 0;
	else
		if(a == b)
			return 1;
		else
			return 0;
}

辅助文件

sqqueue.cpp

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

#include"sqqueue.h" 
typedef  int  QElemType;
void InitQueue(SqQueue &Q)
 { 
   Q.base=(QElemType *)malloc(MAX_QSIZE*sizeof(QElemType));
   if(!Q.base) // 存储分配失败
     exit(OVERFLOW);
   Q.front=Q.rear=0;
 }
// 销毁循环队列Q,Q不再存在
 void DestroyQueue(SqQueue &Q)
 { 
   if(Q.base)
     free(Q.base);
   Q.base=NULL;
   Q.front=Q.rear=0;
 }
// 将Q清为空循环队列
 void ClearQueue(SqQueue &Q)
 { 
   Q.front=Q.rear=0;
 }
// 若循环队列Q为空队列,则返回TRUE;否则返回FALSE
 int QueueEmpty(SqQueue Q)
 { 
   if(Q.front==Q.rear) // 队列空的标志
     return TRUE;
   else
     return FALSE;
 }
// 返回Q的元素个数,即循环队列的长度
 int QueueLength(SqQueue Q)
 { 
   return(Q.rear-Q.front+MAX_QSIZE)%MAX_QSIZE;
 }
// 若循环队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
 int GetHead(SqQueue Q,QElemType &e)
 { 
   if(Q.front==Q.rear) // 队列空
     return ERROR;
   e=Q.base[Q.front];
   return OK;
 }
// 插入元素e为循环队列Q的新的队尾元素
 int EnQueue(SqQueue &Q,QElemType e)
 { 
   if((Q.rear+1)%MAX_QSIZE==Q.front) // 队列满
     return ERROR;
   Q.base[Q.rear]=e;
   Q.rear=(Q.rear+1)%MAX_QSIZE;
   return OK;
 }
// 若循环队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
 int DeQueue(SqQueue &Q,QElemType &e)
 { 
   if(Q.front==Q.rear) // 队列空
     return ERROR;
   e=Q.base[Q.front];
   Q.front=(Q.front+1)%MAX_QSIZE;
   return OK;
 }
// 从队头到队尾依次对队列Q中每个元素调用函数vi()
 void QueueTraverse(SqQueue Q,void(*vi)(QElemType))
 { 
   int i;
   i=Q.front;
   while(i!=Q.rear)
   {
     vi(Q.base[i]);
     i=(i+1)%MAX_QSIZE;
   }
   printf("\n");
 }

sqqueue.h

#ifndef   __SQQUEUE_H__
#define   __SQQUEUE_H__
#include"symbol.h"
#define MAX_QSIZE 20 // 最大队列长度+1

typedef  int  QElemType;
 
struct SqQueue
{
   QElemType *base; // 初始化的动态分配存储空间
   int front; // 头指针,若队列不空,指向队列头元素
   int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
};
void InitQueue(SqQueue &Q);      // 构造一个空循环队列Q 
void DestroyQueue(SqQueue &Q);   // 销毁循环队列Q,Q不再存在
void ClearQueue(SqQueue &Q);   // 将Q清为空循环队列
int QueueEmpty(SqQueue Q);     // 若循环队列Q为空队列,则返回TRUE;否则返回FALSE
int QueueLength(SqQueue Q);      // 返回Q的元素个数,即循环队列的长度
int GetHead(SqQueue Q,QElemType &e); // 若循环队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
int EnQueue(SqQueue &Q,QElemType e);   // 插入元素e为循环队列Q的新的队尾元素
int DeQueue(SqQueue &Q,QElemType &e);  // 若循环队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
void QueueTraverse(SqQueue Q,void(*vi)(QElemType)); // 从队头到队尾依次对队列Q中每个元素调用函数vi()
#endif

sqstack.cpp

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

#include"sqstack.h" 
typedef  int SElemType;
void InitStack(SqStack &S)
{ 
	if(!(S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType))))
     exit(OVERFLOW); // 存储分配失败
    S.top=S.base;
	S.stacksize=STACK_INIT_SIZE; 
}

void DestroyStack(SqStack &S)
{ 
	free(S.base);
	S.base=NULL;
	S.top=NULL;
	S.stacksize=0; 
}

void ClearStack(SqStack &S)
{ 
	S.top=S.base;
}

int StackEmpty(SqStack S)
{
	if(S.top==S.base)
     return TRUE;
	else
     return FALSE; 	
 }

int StackLength(SqStack S)
{ 
	return S.top-S.base;
}

int GetTop(SqStack S,SElemType &e)
{ 
	if(S.top>S.base)
   {
     e=*(S.top-1);
     return OK;
   }
   else
     return ERROR;
 }

void Push(SqStack &S,SElemType e)
{ 
	if(S.top-S.base>=S.stacksize) // 栈满,追加存储空间
	{
     S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
     if(!S.base)
       exit(OVERFLOW); // 存储分配失败
     S.top=S.base+S.stacksize;
     S.stacksize+=STACKINCREMENT;
	}
   *(S.top)++=e; 
}

int Pop(SqStack &S,SElemType &e)
{ 
	if(S.top==S.base)
     return ERROR;
	e=*--S.top;
	return OK;
}

void StackTraverse(SqStack S,void(*visit)(SElemType))
{
	while(S.top>S.base)
		visit(*S.base++);
	printf("\n");
}

sqstack.h

#ifndef   __SQSTACK_H__
#define   __SQSTACK_H__

#include"symbol.h"

#define  STACK_INIT_SIZE   100  //存储空间初始分配量 
#define  STACKINCREMENT    10   //存储空间分配增量  

typedef  int SElemType;

typedef   struct
{          
    SElemType     *base;    //栈的基址即栈底指针          
    SElemType     *top;     //栈顶指针          
   int      stacksize;       //当前分配的空间 
}SqStack; 
void InitStack(SqStack &S);    // 构造一个空栈S
void DestroyStack(SqStack &S); // 销毁栈S,S不再存在
void ClearStack(SqStack &S);   // 把S置为空栈
int StackEmpty(SqStack S);     // 若栈S为空栈,则返回TRUE,否则返回FALSE
int StackLength(SqStack S);    // 返回S的元素个数,即栈的长度
int GetTop(SqStack S,SElemType &e);  // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
void Push(SqStack &S,SElemType e);    // 插入元素e为新的栈顶元素
int Pop(SqStack &S,SElemType &e);     // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
void StackTraverse(SqStack S,void(*visit)(SElemType)); // 从栈底到栈顶依次对栈中每个元素调用函数visit()
#endif

symbol.h文章来源地址https://www.toymoban.com/news/detail-468122.html

#ifndef   __SYMBOL_H__
#define   __SYMBOL_H__

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1

#endif

到了这里,关于栈和队列的综合应用-钓鱼的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 栈和队列的相关功能实现及其基础应用

           前言:栈和队列是常见的数据结构,它们在计算机科学中被广泛应用。栈和队列都是一些元素的集合,它们的主要区别在于数据的组织方式和访问顺序。在栈中,元素的添加和删除都在同一端进行,称为栈顶,而在队列中,元素的添加和删除分别在两端进行,分别称

    2024年02月05日
    浏览(35)
  • 栈和队列OJ题思路分享之栈和队列互换(C语言实现)

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:刷题分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你刷更多C语言和数据结构的题!   🔝🔝 我们紧接上一章的刷题分享来把后面两个题给搞定,它们分别是: 1. 用队列实现栈: 力扣225题— 2. 用栈实现队列: 力扣232题.

    2024年02月03日
    浏览(40)
  • 第 3 章 栈和队列 (循环队列)

    1. 背景说明 和顺序栈相类似,在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外, 尚需附设两个指针 front 和 rear 分别指示队列头元素及队列尾元素的位置。约定:初始化建空队列时,令 fronts = rear = 0, 每当插入新的队列尾元素

    2024年02月10日
    浏览(33)
  • 第 3 章 栈和队列(单链队列)

    1. 背景说明 队列(queue)是一种先进先出(first in first out,缩为 FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。 2. 示例代码 1)status.h 2) linkQueue.h 3) linkQueue.c 4) auxiliary.h 5) auxiliary.c 6) main.c 3. 输出示例 注意: free() 函数的作用仅仅是把指针指向的内存释放,并

    2024年02月10日
    浏览(31)
  • 【数据结构】栈和队列(队列篇)

    上期我们已经学习了数据结构中的栈,这期我们开始学习队列。 目录 1.队列的概念及结构 2.队列的实现 队列结构体定义 常用接口函数 初始化队列 队尾入队列 队头出队列 获取队列头部元素、 获取队列队尾元素 获取队列中有效元素个数 检测队列是否为空 销毁队列 3.循环队

    2024年02月13日
    浏览(42)
  • 用队列实现栈和用栈实现队列

    前面我们实现了栈和队列,其实栈和队列之间是可以相互实现的 下面我们来看一下 用 队列实现栈 和 用栈实现队列 使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty) 实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。 int pop

    2023年04月09日
    浏览(37)
  • (※)力扣刷题-栈和队列-用栈实现队列

    使用栈实现队列的下列操作: push(x) – 将一个元素放入队列的尾部。 pop() – 从队列首部移除元素。 peek() – 返回队列首部的元素。 empty() – 返回队列是否为空。 说明: 你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。 你所使用

    2024年02月07日
    浏览(41)
  • 【数据结构】栈和队列(链表模拟队列)

      学习本章节必须具备 单链表的前置知识, 建议提前学习:点击链接学习:单链表各种功能函数 细节 详解 本章节是学习用 单链表模拟队列 1. 单链表实现队列 思路如下 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先 进先出

    2024年04月27日
    浏览(44)
  • 数据结构之栈和队列 - 超详细的教程,手把手教你认识并运用栈和队列

    栈:后进先出 队列:先进先出 栈:是一种特殊的 线性表 , 只允许在固定的一端插入或者删除元素 ,一个栈包含了栈顶和栈底。只能在栈顶插入或者删除元素。 栈的底层 是由 数组 实现的。 栈遵循先入后出原则,也就是先插入的元素得到后面才能删除,后面插入的元素比

    2024年02月07日
    浏览(85)
  • 数据结构---栈和队列

    栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作

    2024年01月18日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包