栈
一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操 作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。不含任 何元素的栈称为空栈,同样栈可以分为顺序栈和链栈。
栈的结构:
栈特性:后进先出(LILO)特殊线性表 。
栈功能:将数据从一种序列改变到另一种序列 。
顺序栈的结构c语言描述:
typedef struct Stack
{
SDataType _array[MAXSIZE];
int _top; // 标记栈顶(栈中元素的个数)
}Stack;
栈的基本操作:
void StackInit(Stack* ps)//初始化
{
ps->_top = -1;
}
void StackPush(Stack* ps, SDataType data)//进栈
{
assert(ps);
if (ps->_top == MAXSIZE - 1)
printf("栈已满\n");
else
{
ps->_top++;
ps->_array[ps->_top] = data;
}
}
void StackPop(Stack* ps)//出栈
{
assert(ps);
if (ps->_top == -1)
printf("栈已空\n");
ps->_top--;
}
SDataType StackTop(Stack* ps)//获取站顶元素
{
assert(ps);
if (ps->_top == -1)
printf("栈已空\n");
return ps->_array[ps->_top];
}
int StackSize(Stack* ps)//栈中的元素个数
{
return (ps->_top) + 1;
}
int StackEmpty(Stack* ps)//判空
{
if (ps->_top == -1)
return 1;
else
return 0;
}
栈的练习题:
括号匹配问题;
首先检测获取的元素是否是括号,如果是那么检测是否是左括号,如果是那么将该元素进栈,如果不是左括号检测是否是右括号若果是此时要判断栈是否为空(栈空那么表示右括号多于左括号,如果栈不为空判断两个括号是否匹配如果不匹配那么则匹配出错)出循环判断栈是否为空不为空表示左比右多。否则匹配正确
1.
//判断元素是否是括号
int IsBrackets(char arr[], int i)
{
if ((arr[i] == '(') || (arr[i] == '[') || (arr[i] == '{') || (arr[i] == ')') || (arr[i] == ']') || (arr[i] == '}'))
return 1;
return 0;
}
void MatchBrackets(Stack* ps, int sz, char arr[])
{
assert(ps);
int i = 0;
while (i < sz)
{
if (IsBrackets(arr, i))
{
if ((arr[i] == '(') || (arr[i] == '[') || (arr[i] == '{'))
{
StackPush(ps, arr[i]);
i++;
continue;
}
else if((arr[i] ==')') || (arr[i] == ']') || (arr[i] == '}'))
{
if (StackEmpty(ps))
{
printf("右括号比做坐括号多\n");
return;
}
else
{
if ((arr[i] == ')'&&StackTop(ps) == '(') || (arr[i] == ']'&&StackTop(ps) == '[') || (arr[i] == '}'&&StackTop(ps) == '{'))
{
StackPop(ps);
i++;
continue;
}
else
{
printf("匹配出错\n");
return;
}
}
}
}
i++;
}
if (!StackEmpty(ps))
{
printf("左括号比右括号多\n");
}
else
printf("匹配正确\n");
}
后缀表达式:
12*(3+4)-6+8/2 —–> 12 3 4 + * 6 - 8 2 / +
考虑到在有较大数参与运算时不好处理,现将表达式封装成一个数组,再将数组传给函数如下:
operate cal[] = { { DATA, 12 }, { DATA, 3 }, { DATA, 4 }, { ADD, 0 }, { MUL, 0 },
{ DATA, 6 }, { SUB, 0 }, { DATA, 8 }, { DATA, 2 }, { DIV, 0 }, { ADD, 0 } };
所需结构体
typedef struct Stack
{
SDataType _array[MAXSIZE];
int _top; // 标记栈顶(栈中元素的个数)
}Stack;
enum Calc
{
ADD,
SUB,
MUL,
DIV,
DATA
};
typedef struct operate
{
enum calc op;
int _data;
}operate;
函数实现:
int CalcRPN(operate *cal, Stack *ps, int size)
{
int i = 0;
int right = 0;
int left = 0;
int ch = 0;
while (i < size)
{
if (cal->op == DATA)
StackPush(ps, cal->_data);//12*(3+4)-6+8/2 —–> 12 3 4 + * 6 - 8 2 / +
else
{
ch = cal->op;
right = StackTop(ps);
StackPop(ps);
left = StackTop(ps);
StackPop(ps);
switch (ch)
{
case ADD:StackPush(ps, left + right);
break;
case SUB:StackPush(ps, left - right);
break;
case MUL:StackPush(ps, left * right);
break;
case DIV:
if (right == 0)
{
printf("除数为0,非法!!!\n");
return 0;
}
else
{
StackPush(ps, left / right);
}
break;
default:printf("操作数非法!!\n"); break;
}
}
i++;
cal++;
}
return StackTop(ps);
}