栈:特殊的线性表(只允许在一边进行操作),分顺序栈(顺序表实现),链栈(链表实现)
特点:后进先出
顺序栈:
栈头在线性表表表尾(线性表表尾插入删除时间复杂度都是O(1))
定义:
typedef struct Stack
{
int *elem;
int top; //栈顶指针,当前可以存放数据的下标
int stacksize; //栈的总格子数
}Stack,*PStack;
链栈:
栈头在链表表表头(链表表头插入删除时间复杂度都是O(1))
定义:
typedef struct SNode
{
int data;
struct SNode *next;
}SNode,*PLStack;
利用栈特点解决实际问题
eg1:判断括号是否匹配
(遇到左括号就入栈,遇到右括号,先把右括号置成左括号,栈顶元素出栈,与出栈元素比较,相等,指针后移,不等则不匹配)
bool match(char *str)
{
Stack s;
InitStack(&s);
while(*str !='\0')
{
if(*str=='(' || *str=='[' || *str=='{')
{
Push(&s,*str);
}
else if(*str==')')
{
*str='(';
int tmp;
Pop(&s,&tmp);
if(*str!=tmp)
{
return false;
}
}
else if(*str==']')
{
*str='[';
int tmp;
Pop(&s,&tmp);
if(*str!=tmp)
{
return false;
}
}
else if(*str=='}')
{
*str='{';
int tmp;
Pop(&s,&tmp);
if(*str!=tmp)
{
return false;
}
}
str++;
}
return true;
}
eg2.编程对一个逆波兰式(后缀表达式)进行求值,如“435*+23*-”的结果是13,函数的参数为字符串(后缀表达式),假定字符串为正确的逆波兰式。
(只要遇到数字就入栈,遇到运算符,就从栈顶出两个值,判断是什么运算符,将出栈元素运算结果入栈)
int getvalue(char *str)
{
int val=0;
Stack s;
InitStack(&s);
while(*str !='\0')
{
int tmp1;
int tmp2;
if(isdigit(*str))
{
Push(&s,*str-'0');
}
else
{
Pop(&s,&tmp1);
Pop(&s,&tmp2);
if(*str=='+')
{
val=tmp2+tmp1;
}
else if(*str=='-')
{
val=tmp2-tmp1;
}
else if(*str=='*')
{
val=tmp2*tmp1;
}
else
{
val=tmp2/tmp1;
}
Push(&s,val);
}
str++;
}
return val;
}