封装栈的基本操作及栈的应用

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 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(逆波兰表达式–后缀表达式)求值
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kevin980123/article/details/83620128