目录
一、设计要求
二、实现方法
三、实现过程
1.链栈的实现
2.前缀表达式变后缀表达式
3.括号匹配
4.链队列的实现
5.队列实现栈
6.应用代码实现汇总
7.小猫钓鱼
文章只写了代码的实现,并未进行原理的讲解,希望大家不喜勿喷
1.栈的有关操作*
要求实现对链栈的入栈和出栈操作。
2.栈的应用举例**
利用链栈实现中缀表达式变成后缀表达式、括号匹配问题。
3.队列的有关操作*
实现对链队列的入队和出队操作,通过链队列实现队列实现栈。
4.栈和队列的综合应用举例**
综合链栈和链队列实现小猫钓鱼游戏。
编辑器:VS2019
语言:主要是以C语言为主,结合了c++的引用。所以文件后缀名要用 .cpp
实现原理:先实现链栈和链队列的增删查改和取长度、判空等方法,再此基础之上来实现相关的应用。
先创建一个头文件Stack.h,将所需的头文件和方法名先包含在里面。
在创建StackCode.cpp文件,用于实现方法。
Stack.h文件源码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
typedef char ElemType;//栈中的数据类型为char
//typedef int ElemType;//用于小猫钓鱼,记得切换
typedef struct stack {
ElemType data;
struct stack* next;
}StackNode, * LinkStackNode;
void InitStack(LinkStackNode& L);//初始化
LinkStackNode CreatNode(ElemType e);//创建一个新节点
void StackPush(LinkStackNode& L, ElemType e);//栈插入
void StackPop(LinkStackNode& L, ElemType& e);//出栈
void GetStackTop(LinkStackNode& L,ElemType& e);//取栈顶元素
bool StackEmpty(LinkStackNode& L);//判空
int StackSize(LinkStackNode L);//取栈大小
void DestroyStack(LinkStackNode& L);//栈的销毁
void Print(LinkStackNode L);//打印
StackCode.cpp文件源码
#include"Stack.h"
void InitStack(LinkStackNode& L)
{
L = NULL;
}
LinkStackNode CreatNode(ElemType e)
{
LinkStackNode newnode = (LinkStackNode)malloc(sizeof(StackNode));
if (!newnode)
{
printf("malloc is fail\n");
exit(-1);
}
//新节点赋值
newnode->data = e;
newnode->next = NULL;
return newnode;
}
void StackPush(LinkStackNode& L, ElemType e)
{
LinkStackNode newnode = CreatNode(e);//创建一个节点
newnode->next = L;//相当于头插到链中
L = newnode;//换头节点
}
void StackPop(LinkStackNode& L, ElemType& e) {
if (L == NULL)
{
printf("L is NULL\n");
exit(-1);
}
LinkStackNode next = L->next;//取头的下一个节点
e = L->data;
free(L);
L = next;//使L再次指向头位置
}
void GetStackTop(LinkStackNode& L, ElemType& e) {
if (L == NULL)
{
printf("L is NULL\n");
return;
}
e = L->data;
}
void DestroyStack(LinkStackNode& L) {
LinkStackNode cur = L;
while (cur) {
L = L->next;
free(cur);
cur = L;
}
}
int StackSize(LinkStackNode L)
{
LinkStackNode cur = L;
int count = 0;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
bool StackEmpty(LinkStackNode& L) {
return L == NULL;
}
void Print(LinkStackNode L)
{
LinkStackNode cur = L;
while (cur)
{
//printf("%d->", cur->data);
std::cout << cur->data << "->";
cur = cur->next;
}
printf("NULL\n");
}
测试代码:
void test_Stack()
{
printf("*********栈的出入操作************\n");
LinkStackNode stack;
InitStack(stack);
//入栈数据
printf("请输入入栈元素个数:\n");
int n;
scanf("%d", &n);
printf("请依次输入入栈的元素(字符类型)\n");
for (int i = 0; i < n; i++)
{
ElemType val;
std::cin >> val; //c++的输入,比较方便所以这里使用了,也可以改为c的scanf
StackPush(stack, val);
}
printf("入栈元素为:\n");
Print(stack);
printf("请选择:1.入栈 2.出栈 3.释放栈空间\n");
int option;
while (std::cin>>option)
{
switch (option)
{
case 1:ElemType elem;
printf("请输入入栈元素\n");
std::cin >> elem;
StackPush(stack, elem);
printf("入栈后为:\n");
Print(stack);
break;
case 2:
ElemType e;
StackPop(stack, e);
std::cout << "出栈元素为" << e << ", 出栈后栈为:" << std::endl;//c++的打印,可以改用c的printf
Print(stack);
break;
case 3:
DestroyStack(stack);
printf("栈空间以释放\n");
system("pause");
return;
break;
default:
printf("输入错误,请重新输入\n");
}
std::cout << "请选择"<
int Return_Prio(char c) //计算运算符的优先级
{
if (c == '+' || c == '-')
return 1;
else if (c == '*' || c == '/' || c == '%')
return 2;
else if (c == '^')
return 3;
else
return 0;
}
//中缀变后缀
void mid_to_postfix(char* str,char* ans)
{
ElemType elem;//栈出来的元素
int j = 0;
LinkStackNode L;
InitStack(L);
//出入元素
for (int i = 0; i < strlen(str); i++)
{
//取元素
char c = str[i];
//判断单个元素,进行出入栈进行匹配
switch (c)
{
//如果是运算符,则进行比较,高于栈顶优先级则入栈,低于栈顶优先级则出栈到后缀
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
while (!StackEmpty(L))//栈非空时
{
//将优先级大于c的全部入后缀
GetStackTop(L, elem);
if (Return_Prio(elem) >= Return_Prio(c))
{
ans[j++] = elem;//入后缀
StackPop(L, elem);//删除改栈顶
}
else
{
break;
}
}
StackPush(L, c);//将str的算术符入栈
break;
//括号比较
case '(':
StackPush(L, c);//左括号直接入栈
break;
case ')'://如果时右括号,就一直出栈入后缀,直到左括号
StackPop(L, elem);
while (elem != '(')
{
ans[j++] = elem;
StackPop(L, elem);
}
break;
default:ans[j++] = c;//操作数,直接入后缀
}
}
//将栈中剩余的算术符全部出栈
while (!StackEmpty(L))
{
StackPop(L, elem);
ans[j++] = elem;
}
ans[j] = '\0';
DestroyStack(L);
}
void test_mid_to_postfix()
{
printf("请输入一个中缀表达式\n");
char s[100];
scanf("%s", s);
char postfix[100];
mid_to_postfix(s, postfix);
printf("其后缀表达式为%s\n", postfix);
system("pause");
}
bool chkParenthesis(char* A, int n)
//判断是否满足匹配
{
LinkStackNode st;
InitStack(st);
char tmp;
for (int i = 0; i < n; i++)
{
char c = A[i];
switch (c)
{
//左括号入栈
case '(':
StackPush(st, c);
break;
case '[':
StackPush(st, c);
break;
case '{':
StackPush(st, c);
break;
//右括号出栈,前提判断栈顶是否为左括号与之匹配
case ')':
GetStackTop(st, tmp);
if (StackEmpty(st) || tmp != '(')
return false;
else
StackPop(st, tmp);
break;
case ']':
GetStackTop(st, tmp);
if (StackEmpty(st) || tmp != '[')
return false;
else
StackPop(st, tmp);
break;
case '}':
GetStackTop(st, tmp);
if (StackEmpty(st) || tmp != '{')
return false;
else
StackPop(st, tmp);
break;
default:return false;//其他字符直接fasle
}
}
if (!StackEmpty(st))//栈为空才表名括号是匹配的
return false;
return true;
}
void test_chkParenthesis()
{
printf("请输入需要判断的括号\n");
char A[100];
scanf("%s", A);
int n = strlen(A);
bool res= chkParenthesis(A, n);
if (res)
printf("结果为:true\n");
else
printf("结果为:false\n");
system("pause");
}
先创建一个头文件Queue.h,将所需的头文件和方法名先包含在里面。
在创建QueueCode.cpp文件,用于实现方法。
Queue.h源码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
typedef char ElemType;//用于队列实现栈时
//typedef int ElemType;//用于小猫钓鱼,记得切换
typedef struct QueueNode
{
struct QueueNode* next;
ElemType data;
}QNode, *LQNode;
typedef struct//设置头尾指针
{
LQNode head;
LQNode tail;
}Queue;
void QueueInit(Queue& Q);//初始化
void QueuePush(Queue& Q,ElemType e);//入队
void QueuePop(Queue& Q,ElemType &e);//出队
bool QueueEmpty(Queue Q);//判空
int QueueSize(Queue Q);//求队列大小
ElemType GetQueueTop(Queue Q);//去队头元素
int GetQueueBack(Queue Q);//去队尾元素
void QueueDestroy(Queue& Q);//释放空间
void QueuePrint(Queue Q);
QueueCode.cpp源码
#include"Queue.h"
void QueueInit(Queue& Q)
{
//创建头
Q.head = (LQNode)malloc(sizeof(QNode));
if (!Q.head)
{
printf("malloc is fail\n");
exit(-1);
}
Q.head->next = NULL;
Q.tail = Q.head;
}
void QueuePush(Queue& Q,ElemType e) {
//创建节点
LQNode p = (LQNode)malloc(sizeof(QNode));
if (!p)
{
printf("malloc is fail\n");
exit(-1);
}
p->data = e;
p->next = Q.tail->next;
Q.tail->next = p;
Q.tail = p;
}
void QueuePop(Queue& Q, ElemType& e)
{
if (Q.head == Q.tail)
{
printf("Q is NULL\n");
return;
}
//指向待删除的结点
LQNode p = Q.head->next;
e = p->data;
//链接删除节点后面的链
Q.head->next = p->next;
if (Q.tail == p)//如果删除是尾节点,则删后链为空,尾就要与头相等
{
Q.tail = Q.head;
}
free(p);
}
bool QueueEmpty(Queue Q)
{
if (Q.head == Q.tail)
return true;
return false;
}
int QueueSize(Queue Q)
{
LQNode tmp = Q.head->next;
if (Q.head == Q.tail)
{
printf("Q is NULL\n");
return 0;
}
int count = 0;
while (tmp != NULL)
{
tmp = tmp->next;
count++;
}
return count;
}
void QueueDestroy(Queue& Q)
{
LQNode tmp = Q.head->next;
//释放每一个节点
while (tmp)
{
LQNode next = tmp->next;
free(tmp);
tmp = next;
}
Q.head = Q.tail;
}
ElemType GetQueueTop(Queue Q)
{
if (Q.head->next==NULL)
return '0';
return (Q.head->next)->data;
}
int GetQueueBack(Queue Q)
{
return (Q.tail)->data;
}
void QueuePrint(Queue Q)
{
LQNode tmp= Q.head->next;
if (Q.head == Q.tail)
{
printf("Q is NULL\n");
return;
}
while (tmp !=NULL)
{
//printf("%d->", tmp->data);
std::cout << tmp->data<<"->";
tmp = tmp->next;
}
printf("NULL\n");
}
typedef struct {
Queue first;
Queue second;
} MyStack;//两个队列实现栈
MyStack* myStackCreate() {//初始化
MyStack* node = (MyStack*)malloc(sizeof(MyStack));
QueueInit(node->first);
QueueInit(node->second);//从外到内初始化
return node;
}//初始化
void myStackPush(MyStack* obj, ElemType x) {
//入栈即往非空入队列
if (!QueueEmpty(obj->first))
{
QueuePush(obj->first, x);
}
else
{
QueuePush(obj->second, x);
}
}
ElemType myStackPop(MyStack* obj) {
//出栈即非空出队列到拎一个空队列,剩下最后一个元素即为出栈元素
assert(obj);
ElemType rval;
if (!QueueEmpty(obj->first))
{
while (QueueSize(obj->first) > 1)//直到最后一个元素之前
{
QueuePush(obj->second, GetQueueTop(obj->first));
QueuePop(obj->first,rval);
}
//清空该队列,使变为空
ElemType cur = GetQueueTop(obj->first);
QueuePop(obj->first,rval);
return cur;
}
else
{
while (QueueSize(obj->second) > 1)
{
QueuePush(obj->first, GetQueueTop(obj->second));
QueuePop(obj->second,rval);
}
ElemType cur = GetQueueTop(obj->second);
QueuePop(obj->second, rval);
return cur;
}
}
ElemType myStackTop(MyStack* obj) {
assert(obj);
if (!QueueEmpty(obj->first))//非空队列取
return GetQueueBack(obj->first);//栈顶元素相当于队列尾元素
else
return GetQueueBack(obj->second);
}
bool myStackEmpty(MyStack* obj) {
assert(obj);
if (QueueEmpty(obj->first) && QueueEmpty(obj->second))//两队列全空为空
return true;
else
return false;
}
void myStackFree(MyStack* obj) {
//销毁改“栈”
QueueDestroy(obj->first);
QueueDestroy(obj->second);
free(obj);
obj = NULL;//从内到外销毁
}
void test_Queeu_to_Staack()
{
char s[100];
printf("请输入队列模拟栈的入栈元素:\n");
scanf("%s", s);
printf("入栈后为:");
int len = strlen(s);
for (int i = 0; i < len; i++)
{
printf("%c ", s[i]);
}
printf("\n");
MyStack* myst;
myst=myStackCreate();
for (int i = 0; i < strlen(s); i++)
{
myStackPush(myst, s[i]);
}
ElemType e=0;
printf("栈顶元素为:%c\n", myStackTop(myst));
e = myStackPop(myst);
printf("出栈一个元素后栈顶元素为:%c\n", myStackTop(myst));
myStackFree(myst);
system("pause");
}
以上中缀表达式变后缀表达式、括号匹配、队列实现栈的应用写在一个test.cpp文件中,然后编写一个菜单,进行选择要进行的应用操作。小猫钓鱼单独写一个文件实现。
test.cpp
#include"Stack.h"
#include"Queue.h"
#include
#include
#include
#include
#include
/************************************************/
//栈出入测试
void test_Stack()
{
printf("*********栈的出入操作************\n");
LinkStackNode stack;
InitStack(stack);
//入栈数据
printf("请输入入栈元素个数:\n");
int n;
scanf("%d", &n);
printf("请依次输入入栈的元素(字符类型)\n");
for (int i = 0; i < n; i++)
{
ElemType val;
std::cin >> val;
StackPush(stack, val);
}
printf("入栈元素为:\n");
Print(stack);
printf("请选择:1.入栈 2.出栈 3.释放栈空间\n");
int option;
while (std::cin>>option)
{
switch (option)
{
case 1:ElemType elem;
printf("请输入入栈元素\n");
std::cin >> elem;
StackPush(stack, elem);
printf("入栈后为:\n");
Print(stack);
break;
case 2:
ElemType e;
StackPop(stack, e);
std::cout << "出栈元素为" << e << ", 出栈后栈为:" << std::endl;
Print(stack);
break;
case 3:
DestroyStack(stack);
printf("栈空间以释放\n");
system("pause");
return;
break;
default:
printf("输入错误,请重新输入\n");
}
std::cout << "请选择"<> n;
printf("请输入入队元素\n");
for (int i = 0; i < n; i++)
{
ElemType val;
std::cin >> val;
QueuePush(Q, val);
}
printf("入队后为:\n");
QueuePrint(Q);
printf("请选择:1.入队 2.出队 3.释放队列空间\n");
int op;
//std::cin >> op;
while (std::cin >> op)
{
switch (op)
{
case 1:
printf("请输入入队元素\n");
ElemType elem;
std::cin >> elem;
QueuePush(Q, elem);
printf("入队后为:\n");
QueuePrint(Q);
break;
case 2:
ElemType e;
QueuePop(Q, e);
std::cout << "出队元素为" << e << "出对后为:\n";
QueuePrint(Q);
break;
case 3:
std::cout << "队列已销毁" << std::endl;
QueueDestroy(Q);
system("pause");
return;
break;
default:
printf("输入错误,请重新输入\n");
}
printf("请选择:\n");
}
}
/**********************************************/
//中缀表达式变后缀表达式
//先比较算术符优先级
int Return_Prio(char c)
{
if (c == '+' || c == '-')
return 1;
else if (c == '*' || c == '/' || c == '%')
return 2;
else if (c == '^')
return 3;
else
return 0;
}
//中缀变后缀
void mid_to_postfix(char* str,char* ans)
{
ElemType elem;//栈出来的元素
int j = 0;
LinkStackNode L;
InitStack(L);
//出入元素
for (int i = 0; i < strlen(str); i++)
{
//取元素
char c = str[i];
//判断单个元素,进行出入栈进行匹配
switch (c)
{
//如果是运算符,则进行比较,高于栈顶优先级则入栈,低于栈顶优先级则出栈到后缀
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
while (!StackEmpty(L))//栈非空时
{
//将优先级大于c的全部入后缀
GetStackTop(L, elem);
if (Return_Prio(elem) >= Return_Prio(c))
{
ans[j++] = elem;//入后缀
StackPop(L, elem);//删除改栈顶
}
else
{
break;
}
}
StackPush(L, c);//将str的算术符入栈
break;
//括号比较
case '(':
StackPush(L, c);//左括号直接入栈
break;
case ')'://如果时右括号,就一直出栈入后缀,直到左括号
StackPop(L, elem);
while (elem != '(')
{
ans[j++] = elem;
StackPop(L, elem);
}
break;
default:ans[j++] = c;//操作数,直接入后缀
}
}
//将栈中剩余的算术符全部出栈
while (!StackEmpty(L))
{
StackPop(L, elem);
ans[j++] = elem;
}
ans[j] = '\0';
DestroyStack(L);
}
void test_mid_to_postfix()
{
printf("请输入一个中缀表达式\n");
char s[100];
scanf("%s", s);
char postfix[100];
mid_to_postfix(s, postfix);
printf("其后缀表达式为%s\n", postfix);
system("pause");
}
/***********************************************************/
//括号匹配 //ElemType为int时,不能用;
bool chkParenthesis(char* A, int n)
{
LinkStackNode st;
InitStack(st);
char tmp;
for (int i = 0; i < n; i++)
{
char c = A[i];
switch (c)
{
//左括号入栈
case '(':
StackPush(st, c);
break;
case '[':
StackPush(st, c);
break;
case '{':
StackPush(st, c);
break;
//右括号出栈,前提判断栈顶是否为左括号与之匹配
case ')':
GetStackTop(st, tmp);
if (StackEmpty(st) || tmp != '(')
return false;
else
StackPop(st, tmp);
break;
case ']':
GetStackTop(st, tmp);
if (StackEmpty(st) || tmp != '[')
return false;
else
StackPop(st, tmp);
break;
case '}':
GetStackTop(st, tmp);
if (StackEmpty(st) || tmp != '{')
return false;
else
StackPop(st, tmp);
break;
default:return false;//其他字符直接fasle
}
}
if (!StackEmpty(st))//栈为空才表名括号是匹配的
return false;
return true;
}
void test_chkParenthesis()
{
printf("请输入需要判断的括号\n");
char A[100];
scanf("%s", A);
int n = strlen(A);
bool res= chkParenthesis(A, n);
if (res)
printf("结果为:true\n");
else
printf("结果为:false\n");
system("pause");
}
/********************************************************/
//队列实现栈
typedef struct {
Queue first;
Queue second;
} MyStack;//两个队列实现栈
MyStack* myStackCreate() {//初始化
MyStack* node = (MyStack*)malloc(sizeof(MyStack));
QueueInit(node->first);
QueueInit(node->second);//从外到内初始化
return node;
}//初始化
void myStackPush(MyStack* obj, ElemType x) {
//入栈即往非空入队列
if (!QueueEmpty(obj->first))
{
QueuePush(obj->first, x);
}
else
{
QueuePush(obj->second, x);
}
}
ElemType myStackPop(MyStack* obj) {
//出栈即非空出队列到拎一个空队列,剩下最后一个元素即为出栈元素
assert(obj);
ElemType rval;
if (!QueueEmpty(obj->first))
{
while (QueueSize(obj->first) > 1)//直到最后一个元素之前
{
QueuePush(obj->second, GetQueueTop(obj->first));
QueuePop(obj->first,rval);
}
//清空该队列,使变为空
ElemType cur = GetQueueTop(obj->first);
QueuePop(obj->first,rval);
return cur;
}
else
{
while (QueueSize(obj->second) > 1)
{
QueuePush(obj->first, GetQueueTop(obj->second));
QueuePop(obj->second,rval);
}
ElemType cur = GetQueueTop(obj->second);
QueuePop(obj->second, rval);
return cur;
}
}
ElemType myStackTop(MyStack* obj) {
assert(obj);
if (!QueueEmpty(obj->first))//非空队列取
return GetQueueBack(obj->first);//栈顶元素相当于队列尾元素
else
return GetQueueBack(obj->second);
}
bool myStackEmpty(MyStack* obj) {
assert(obj);
if (QueueEmpty(obj->first) && QueueEmpty(obj->second))//两队列全空为空
return true;
else
return false;
}
void myStackFree(MyStack* obj) {
//销毁改“栈”
QueueDestroy(obj->first);
QueueDestroy(obj->second);
free(obj);
obj = NULL;//从内到外销毁
}
void test_Queeu_to_Staack()
{
char s[100];
printf("请输入队列模拟栈的入栈元素:\n");
scanf("%s", s);
printf("入栈后为:");
int len = strlen(s);
for (int i = 0; i < len; i++)
{
printf("%c ", s[i]);
}
printf("\n");
MyStack* myst;
myst=myStackCreate();
for (int i = 0; i < strlen(s); i++)
{
myStackPush(myst, s[i]);
}
ElemType e=0;
printf("栈顶元素为:%c\n", myStackTop(myst));
e = myStackPop(myst);
printf("出栈一个元素后栈顶元素为:%c\n", myStackTop(myst));
myStackFree(myst);
system("pause");
}
/**********************************************************/
/**********************************************************/
//菜单
void menu()
{
printf("*******************************************************\n");
printf("*******************************************************\n");
printf("********1.栈的出入 2.队列的出入 *********\n");
printf("********3.中缀变后缀表达式 4.括号匹配 *********\n");
printf("********5.队列实现栈 6.银行取钱模拟 *********\n");
printf("******** 0.退出 *********\n");
printf("*******************************************************\n");
printf("*******************************************************\n");
printf("请选择:\n");
}
int main()
{
menu();
int op;
while (std::cin >> op)
{
switch(op)
{
case 0:
printf("程序已退出...\n");
exit(0);
break;
case 1:
test_Stack();
break;
case 2:
test_Queue();
break;
case 3:
test_mid_to_postfix();
break;
case 4:
test_chkParenthesis();
break;
case 5:
test_Queeu_to_Staack();
break;
case 6:
test_Bank();
break;
default:
printf("选择错误,请重新选择\n");
}
system("cls");
menu();
}
return 0;
}
小猫钓鱼是栈和队列的综合应用,这里需要将Stack.h和Queue.h中的typedef char ElemType;改为typedef int ElemType;下面将小猫钓鱼单独用一个fish_cat.cpp文件来写:
#include"Stack.h"
#include"Queue.h"
#include
#include
void Test_cat_fish() {
Queue Q1, Q2;//玩家1 2,出牌为队列的形式
LinkStackNode s;//栈 ,桌子上的牌 ,收派即为出栈
//初始化队列,两人手中都还没有牌
QueueInit(Q1);
QueueInit(Q2);
InitStack(s);//桌子上没有牌
int book[10];//记录桌面上是否存在0~9的牌
for (int i = 1; i <= 9; i++) {
book[i] = 0;
}
int N;
//发牌
printf("请输入发牌数:\n");
scanf("%d", &N);
printf("请为玩家1发牌:\n");
for (int i = 1; i <= N; i++) {
int card_val;
std::cin >> card_val;
QueuePush(Q1, card_val);
}
printf("请为玩家2发牌:\n");
for (int i = 1; i <= N; i++) {
int card_val;
std::cin >> card_val;
QueuePush(Q2, card_val);
}
//打牌中....
while (!QueueEmpty(Q1) && !QueueEmpty(Q2)) {
ElemType push_card = GetQueueTop(Q1);//玩家一所出的牌
if (book[push_card] == 0) { //检查桌面上是否有改牌,没有就入栈(桌)
ElemType tmp;
QueuePop(Q1, tmp);//将此牌出队
StackPush(s, push_card); //打出的牌放到桌子上,入栈
book[push_card] = 1;//标记此牌,已存在
}
else {//桌面有所出的牌,先将改牌出,再收牌,入队位
ElemType tmp;
QueuePop(Q1, tmp);//先出牌,不入栈了,直接入队尾
QueuePush(Q1, push_card);//将赢的牌入队尾
ElemType top_val;//栈顶元素
GetStackTop(s, top_val);
while (top_val != push_card) {//赢得牌依次放到队尾
book[top_val] = 0;//取消标记
StackPop(s, tmp);//出栈
QueuePush(Q1, top_val); //放到队尾
GetStackTop(s, top_val);//再取栈顶元素判断
}
//此时栈顶元素等于push_val,则将此牌,出栈入队列
StackPop(s, tmp);
book[tmp] = 0;
QueuePush(Q1, top_val);
}
//判断玩家是否有手牌
if (QueueEmpty(Q1)) {
break;
}//手中的牌打完,游戏结束,玩家一输
//玩家二出牌
push_card = GetQueueTop(Q2);
if (book[push_card] == 0) {//桌面没有次牌
ElemType tmp;
QueuePop(Q2, tmp); //该牌出队
StackPush(s, push_card);//入栈
book[push_card] = 1;//标记
}
else { //桌上有相同大小的牌
ElemType tmp;
QueuePop(Q2, tmp);//先出牌,不入栈了,直接入队尾
QueuePush(Q2, push_card);//将赢的牌入队尾
ElemType top_val;//栈顶元素
GetStackTop(s, top_val);
while (top_val != push_card) {//赢得牌依次放到队尾
book[top_val] = 0;//取消标记
StackPop(s, tmp);//出栈
QueuePush(Q2, top_val); //放到队尾
GetStackTop(s, top_val);//再取栈顶元素判断
}
//此时栈顶元素等于push_val,则将此牌,出栈入队列
StackPop(s, tmp);
book[tmp] = 0;
QueuePush(Q2, top_val);
if (QueueEmpty(Q2)) {
break;
}
}
}
//判定输赢
if (QueueEmpty(Q2)) {
printf("玩家一赢了!\n");
printf("当前的牌是:\n");
QueuePrint(Q1);
//
if (StackSize(s) > 0) { //桌上有牌输出中上的牌
printf("\n 桌上的牌是:\n");
Print(s);
}
else {
printf("桌上没有牌了!\n");
}
}
else {
printf("玩家二赢!\n");
printf("当前手里的牌是:\n");
QueuePrint(Q2);
if (StackSize(s) > 0) {
printf("\n桌上的牌是:\n");
Print(s);
}
else {
printf("桌上没有牌了!\n");
}
}
system("pause");
}
int main()
{
Test_cat_fish();
return 0;
}