什么是栈?栈是一种特殊的线性表,该线性表规定它的插入运算和删除运算均在线性表的同一端进行。
什么是栈顶?进行插入和删除操作的那一端称为栈顶。
什么是栈底?栈顶的另一端称为栈底。
栈的实现:(1)顺序存储(2)链式存储
以下是栈的C实现
#define MAXSIZE 100
typedef int datatype;
typedef struct {
datatype a[MAXSIZE];
int top;
}sequence_stack
void init_sequence_stack(sequence_stack *st)
{
if(st != null)
st->top = 0;
else
printf("The stack is not allocated\n");
#也许只要一句就可以了,其它的感觉是多余,但为了保护程序异常可能还是需要的 st->top = 0;
}
int is_empty_sequence_stack(sequence_stack *st)
{
//为空时返回1不为空时返回0
return (st->top)? 0 : 1;
}
void print_sequence_stack(sequence_stack *st)
{
sequence_stack tmp;
tmp = *st;
while(tmp->top)
{
printf("%d ",tmp[top-1];)
(tmp->top)--;
}
}
datatype get_top(sequence_stack *st)
{
if(is_empty_sequence_stack(*st))
{printf("the stack is empty\n");exit(1);}
else
return st->[top-1];
}
void push(sequence_stack *st,datatype x)
{
if(st->top >= MAXSIZE)
printf("The stack is full\n");
else
{st->[top] = x; (st->top)++;}
}
void pop(sequence_stack *st)
{
//pop函数弹出栈顶值并且调整栈大小
if(st->top == 0)
printf("The stack is empty\n");
else
st->top--;
}
栈的应用:括号匹配,给出一个字符串序列当中有多个()、{}、[]括号对,要求检验其字符串序列中的括号是否都匹配即"("的下一个括号必须是")","{"的下一个括号必须是"}", "[" 的下一个括号必须是"]"。可以用栈来实现此功能依次从左扫描整个字符串若遇到"(","{","["则进行压栈若遇到")","}" ,"]"则判断是否栈顶元素是与之匹配的括号,若则把栈顶元素弹出,假使最后这个栈大小为0则说明这些括号都匹配了。
匹配的实例:([{}]) 正确
(()()())正确
下面给出括号匹配的C实现
int match_kuohao(char c[])
{
int i,j=0;
sequence_stack *st;
init_sequence_satck(st);
i = strlen(c);
for(j=0;j<i;j++)
{
switch(c[i])
{
case '{':
case '(':
case '[': push(st,c[i]);
case ')': if(!is_empty_sequence_stack(st) && get_top(st) == '(')
{pop(st); break;}
else
return 0;
case ']': if(!is_empty_sequence_stack(st) && get_top(st) == ']')
{pop(st); break;}
else
return 0;
case '}': if(!is_empty_sequence_stack(st) && get_top(st) == '}')
{pop(st);breal;}
else
return 0;
}
j++
}
return is_empty_sequence_stack(st);
}
栈还有一个常用的应用:算术表达式求值
算术表达根据其展现的形式可以分为中缀表达式和后缀表达式
以下是例子
后缀表示式 中缀表达式
3 5 3 *- 3-5*2
3 5-2* (3-5)*2
往往计算机根据一个后缀表达式来求值比较方便,根据后缀表达式求值的思路如下:
假使我们有一个标准的后缀表达式字符串,以"#"标记为结束。如下所示
3.7 2.7 3.9*+#
则算法是:
1)从左到右读入字符串内容若读到是数字则把其压入一个栈
2)若读到的是运算符则把栈顶两个元素弹出做运算操作即为刚读到的那个运算符号,完成后把计算结果压回栈顶
3)处理完字符串中的所有内容,即遇到"#"结束,此时栈顶元素stack[0]即为此表达式的值
那以上问题是有了一个正确的后缀表达式来计算表达式的值但现实中一般出现的是中缀表达式,如何根据中缀表达式来求后缀表达式呢?
《数据结构》李云清书上给出一个算法,反正我是没想出来,或许以后会对我来说很简单
中缀表达式:0.3/(5*2+1)#
算法:(1)从左到右依次扫描中缀表达式的每一个字符,如果是数字字符和圆点则直接将它们写入后缀表达式
(2)如果遇到的是开括号“(”则将它压入操作符栈中,它表明一个新的计算层次的开始,在遇到和它匹配的闭
括号时,将栈中元素弹出并放入后缀表达式中,直到栈顶元素为开括号时“(”,将栈顶元素“(”弹出。表明
这一层括号内的操作处理完毕
(3)如果遇到的是操作符,则将该操作符和操作符栈顶元素比较:
1)当遇到的操作符的优先级小于或等于栈顶元素的优先级时则取出栈顶元素放入后缀表达式,并弹出该栈顶元素,反复
执行直到栈顶元素的优先级小于当前操作符的优先级
2)当所遇到的操作符的优先级大于栈顶元素的优先级时则将它压入栈中
重复上述步骤直到遇到中缀表达式的结束标志“#”,弹出栈中所有元素并放入后缀表达式数组中,转换结束