静态顺序栈的部分实现,括号匹配与逆波兰表达式

一、栈的定义及功能:
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端
称为栈底。不包含任何元素的栈称为空栈,栈又称为后进先出的线性表。
栈特性:后进先出(LILO)特殊线性表
栈功能:将数据从一种序列改变到另一种序列
二、栈的分类:
1、顺序栈:
顺序栈和顺序表数据成员相同,不同之处:顺序栈的入栈和出栈操作只允许对当前栈顶进行操作
顺序栈所有操作时间复杂度为O(1)
2、链式栈

三、静态顺序栈的部分实现(包括初始化,出、入栈,取顶元素,检测是否为空,统计元素个数括号匹配问题和逆波兰表达式)

 

1.    代码及过程

 

 .h

# pragma oncee
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# include<assert.h>
#define MAX_SIZE 10
typedef int DataTYpe;
typedef struct Stack
{
	DataTYpe _array[MAX_SIZE];//有效元素的个数
	int _top; //栈顶元素的位置
}Stack;

//初始化
void StackInit(Stack *s);

//入栈
void StackPush(Stack *s, DataTYpe data);

//出栈
void StackPop(Stack *s);

//取栈顶元素
DataTYpe StackTop(Stack *s);

//有效元素的个数
int StackSize(Stack *s);

//检测栈是否为空
int Stackempty(Stack *s);
 

     .c

# include"Stack.h"
void StackInit(Stack *s)
{
	assert(s);
	s->_top = 0;
}
void StackPush(Stack *s, DataTYpe data)
{
	assert(s);
	if (MAX_SIZE == s->_top)
	{
		printf("栈已满,放不下了");
		return;
	}
	s->_array[s->_top++]=data;
}
void StackPop(Stack *s)
{
	if (Stackempty(s))
		return;
	s->_top--;
}
int Stackempty(Stack *s)
{
	assert(s);
	return 0 == s->_top;
}
DataTYpe StackTop(Stack *s)
{
	assert(!Stackempty(s));
	return s->_array[s->_top - 1];
}
int StackSize(Stack *s)
{
	assert(s);
	return s->_top;
}

 

 test.c

#define _CRT_SECURE_NO_WARNINGS 1
# include"Stack.h"
void test()
{
	Stack s;
	StackInit(&s);
	StackPush(&s, 2);
	StackPush(&s, 3);
	StackPush(&s, 4);
	StackPush(&s, 5);
	printf("size=%d\n", StackSize(&s));
	printf("stacktop=%d\n", StackTop(&s));
	StackPop(&s);
	StackTop(&s);
	printf("size=%d\n", StackSize(&s));
	printf("stacktop=%d\n", StackTop(&s));
}
int main()
{
	test();
	system("pause");
	return 0;
}

结果为:

 

括号匹配问题:

1.取i位置的字符

2.判断字符是否为括号

(1)如果不是括号:继续执行步骤1;

(2)如果是括号:如果为左括号则入栈,然后继续执行步骤1;

 

如果是右括号则用用当前括号与栈顶元素比较:若匹配,则出栈并继续执行步骤1;不匹配则返回。

.h

# pragma oncee
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# include<assert.h>
#define MAX_SIZE 10
typedef int DataTYpe;
typedef struct Stack
{
	DataTYpe _array[MAX_SIZE];//有效元素的个数
	int _top; //栈顶元素的位置
}Stack;

//初始化
void StackInit(Stack *s);

//入栈
void StackPush(Stack *s, DataTYpe data);

//出栈
void StackPop(Stack *s);

//取栈顶元素
DataTYpe StackTop(Stack *s);

//有效元素的个数
int StackSize(Stack *s);

//检测栈是否为空
int Stackempty(Stack *s);

//判断括号是否匹配
int IsBracket(char c);
int MatchBrackets(const char *pStr);

     .c

int IsBracket(char c)
{
	if (('(' == c || ')' == c) ||
		('{' == c || '}' == c) ||
		('[' == c || ']' == c))
	{
		return 1;
	}
	return 0;
}
int MatchBrackets(const char *pStr)
{
	int i = 0;
	Stack s;
	if (NULL == pStr)
		return 0;
	StackInit(&s);
	int len = strlen(pStr);
	for (i = 0; i < len; ++i)
	{
		if (!IsBracket(pStr[i]))
			continue;
		else
		{
			if ('(' == pStr[i] || '{' == pStr[i] || '[' == pStr[i])
				StackPush(&s, pStr[i]);
			else
			{
				if (Stackempty(&s)){
					printf("左括号比右括号少\n");
					return 0;
				}
				char c = StackTop(&s);
				if (('(' == c&&')' == pStr[i]) ||
					('{' == c&&'}' == pStr[i]) ||
					('[' == c&&']' == pStr[i]))
				{
					StackPop(&s);
				}
				else
				{
					printf("左右括号匹配存在问题\n");
					return 0;
				}
			}
		}
	}
	if (!Stackempty(&s))
	{
		printf("左括号比有括号多\n");
		return 0;
	}
	printf("左右括号匹配\n");
	return 1;
}

    test.c

void TestMatchBrackets()
{
	char a[] = "(())abc{[(])}";
	char b[] = "(()))abc{[]}";
	char c[] = "(()()abc{[]}";
	char d[] = "(())abc{[]()}";
	MatchBrackets(a);
	MatchBrackets(b);
	MatchBrackets(c);
	MatchBrackets(d);
}
int main()
{
	TestMatchBrackets();
	system("pause");
	return 0;
}

结果:

逆波兰表达式

1.取数组中的元素

2.判断该元素是否为数字

  若是数字,则入栈,并继续执行步骤1;

  若不是数字,则取栈顶元素为右操作数,出栈;再去栈顶元素为左操作数,出栈

3.进行当前操作,结果入栈,继续执行步骤1

.h

# pragma oncee
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# include<assert.h>
#define MAX_SIZE 10
typedef int DataTYpe;
typedef enum{
	ADD,SUB,MUL,DIV,DATA
}OPERATE;
typedef struct Cell{
	OPERATE _op;
	int data;
}Cell;
typedef struct Stack
{
	DataTYpe _array[MAX_SIZE];//有效元素的个数
	int _top; //栈顶元素的位置
}Stack;

//初始化
void StackInit(Stack *s);

//入栈
void StackPush(Stack *s, DataTYpe data);

//出栈
void StackPop(Stack *s);

//取栈顶元素
DataTYpe StackTop(Stack *s);

//有效元素的个数
int StackSize(Stack *s);

//检测栈是否为空
int Stackempty(Stack *s);

//检测逆波兰数
int CalRPN(Cell RPN[], int size);

     .c

int CalRPN(Cell RPN[], int size)
{
	int i = 0;
	Stack s;
	StackInit(&s);
	for (; i < size; ++i)
	{
		if (RPN[i]._op == DATA)
			StackPush(&s,RPN[i].data);
		else
		{
			int left = 0;
			int 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("除数为非法\n");
					return 0;
 				}
				StackPush(&s, left / right);
				break;
			}
		}
	}
	return StackTop(&s);
}

    test.c

结果:

void TestCalRPN()
{
	Cell RPN[] = { { DATA, 12 }, { DATA, 3 },
	{ DATA, 4 }, { ADD, 0 },
	{ MUL, 0 }, { DATA, 0 },
	{ MUL, 0 }, { DATA, 6 },
	{ SUB, 0 }, { DATA, 8 },
	{ DATA, 2 }, { DIV, 0 },
	{ ADD, 0 } };
	printf("%d\n", CalRPN(RPN, sizeof(RPN) / sizeof(RPN[0])));
}
int main()
{
	TestCalRPN();
	system("pause");
	return 0;
}

 

 

猜你喜欢

转载自blog.csdn.net/xuruhua/article/details/79834311