版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kevin980123 https://blog.csdn.net/kevin980123/article/details/83620128
封装栈的基本操作及栈的应用
用栈解决括号的匹配问题
用栈解决RPN(逆波兰表达式–后缀表达式)求值
程序代码如下:
Stack.h
typedef int SDataType;
//typedef char SDataType;
#define MAXSIZE 10
typedef struct Stack
{
SDataType _array[MAXSIZE];
int _top; // 标记栈顶(栈中元素的个数)
}Stack;
void StackInit(Stack* ps);
void StackPush(Stack* ps, SDataType data);
void StackPop(Stack* ps);
SDataType StackTop(Stack* ps);
int StackSize(Stack* ps);
int StackEmpty(Stack* ps);
Stack.c
#include "stack.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>
//初始化
void StackInit(Stack* ps)
{
assert(ps);
ps->_top = 0;
}
//压栈
void StackPush(Stack* ps, SDataType data)
{
assert(ps);
if (MAXSIZE - 1 == ps->_top)
{
printf("栈已满\n");
return;
}
ps->_array[ps->_top++] = data;
}
//出栈
void StackPop(Stack* ps)
{
assert(ps);
if (1 == StackEmpty(ps))
return;
ps->_top--;
}
//获取栈顶元素
SDataType StackTop(Stack* ps)
{
assert(ps);
return ps->_array[ps->_top-1];
}
//求栈大小
int StackSize(Stack* ps)
{
assert(ps);
return ps->_top;
}
//判断栈是否为空
int StackEmpty(Stack* ps)
{
assert(ps);
return 0 == ps->_top;
}
test.c
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
//1. 封装栈的基本操作
// 建议:静态
#if 0
void TestStack()
{
Stack s;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
printf("size = %d\n", StackSize(&s));
printf("top = %d\n", StackTop(&s));
if (1 == StackEmpty(&s))
printf("栈为空\n");
StackPop(&s);
StackPop(&s);
printf("size = %d\n", StackSize(&s));
printf("top = %d\n", StackTop(&s));
StackPop(&s);
StackPop(&s);
printf("size = %d\n", StackSize(&s));
if (1 == StackEmpty(&s))
printf("栈为空\n");
}
int main()
{
TestStack();
system("pause");
return 0;
}
#endif
//2. 栈的应用
#if 0
//用栈解决括号的匹配问题
int IsBrackets(char c)
{
if (('(' == c || ')' == c) || ('[' == c || ']' == c) || ('{' == c || '}' == c))
return 1;
return 0;
}
void MatchBrackets(const char* str)
{
int i = 0;
int size = 0;
Stack s;
if (NULL == str)
return;
StackInit(&s);
size = strlen(str);
for (i = 0; i < size; ++i)
{
if (IsBrackets(str[i]))
{
//当前字符为左括号
if ('(' == str[i] || '[' == str[i] || '{' == str[i])
{
StackPush(&s, str[i]);
}
//当前字符为右括号
else
{
char c;
if (StackEmpty(&s))
{
printf("右括号多于左括号!\n");
return;
}
//检测当前括号是否与栈顶括号匹配
c = StackTop(&s);
if (('(' == c && ')' == str[i]) ||
('[' == c && ']' == str[i]) ||
('{' == c && '}' == str[i]) )
{
StackPop(&s);
}
else
{
printf("左右括号次序不匹配!\n");
return;
}
}
}
}
if (StackEmpty(&s))
{
printf("左右括号次序匹配:)\n");
return;
}
else
{
printf("左括号多于右括号!\n");
return;
}
}
int main()
{
char a[] = "(())abc{[(])}";//左右括号次序不匹配
char b[] = "(()))abc{[]}";//右括号多于左括号
char c[] = "(()()abc{[]}";//左括号多于右括号
char d[] = "(())abc{[]()}";//左右括号次序匹配
MatchBrackets(a);
MatchBrackets(b);
MatchBrackets(c);
MatchBrackets(d);
system("pause");
return 0;
}
#endif
#if 1
//用栈解决RPN(逆波兰表达式--后缀表达式)求值
typedef enum{ADD,SUB,MUL,DIV,DATA}OPERATOR;
typedef struct Cell
{
OPERATOR _op;
int data;
}Cell;
//12*(3+4)-6+8/2--->12 3 4 + * 6 - 8 2 / +
int CalcRPN(Cell* RPN, int size)
{
int i = 0;
Stack s;
StackInit(&s);
for (i = 0; i < size; ++i)
{
if (DATA == RPN[i]._op)
StackPush(&s, RPN[i].data);
else
{
int left = 0, right = 0;
right = StackTop(&s);
StackPop(&s);
left = StackTop(&s);
StackPop(&s);
switch(RPN[i]._op)
{
case ADD:
StackPush(&s,left + right);
break;
case SUB:
StackPush(&s, left - right);
break;
case MUL:
StackPush(&s, left * right);
break;
case DIV:
if (0 == right)
{
printf("除数为0非法!\n");
return 0;
}
StackPush(&s, left / right);
break;
}
}
}
return StackTop(&s);
}
int main()
{
Cell RPN[] = {{DATA, 12}, {DATA, 3}, {DATA, 4}, {ADD, 0}, {MUL, 0}, {DATA, 6},
{SUB, 0}, {DATA, 8}, {DATA, 2}, {DIV, 0}, {ADD, 0}};
printf("%d\n", CalcRPN(RPN, sizeof(RPN) / sizeof(RPN[0])));
system("pause");
return 0;
}
#endif
程序运行结果如下:
栈的封装:
用栈解决括号的匹配问题
用栈解决RPN(逆波兰表达式–后缀表达式)求值