栈的定义:栈是一种先进后出的数据结构,即先入栈的最后出栈。
因此,对于一个顺序存储结构栈,只允许头添加,尾删除。
链式结构的栈的本质就是限制了操作的链表,那么为什么有了链表还要有栈呢,这其实有些工作场合来决定的,而栈的使用则可以很好地提高工作效率。
如果想了解链表的相关知识,请参见:链表的插入操作
栈的实际应用:
- 括号匹配问题
【算法思想】
在检验算法中设置一个栈。若读入的是左括号,则直接入栈,等待相匹配的同类右括号;若读入的是右括号,且与当前栈顶的左括号同类型,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况。另外,如果输入序列已读尽,而栈中仍有等待匹配的左括号,或者读入了一个右括号,而栈中已无等待匹配的左括号,均属不合法的情况。当输入序列和栈同时变为空时,说明所有括号完全匹配。
2. 表达式求值
【算法思想】
(1)规定优先级表;
(2)设置两个栈:OVS(运算数栈)和OPTR(运算符栈);
(3)自左向右扫描,遇操作符则与OPTR栈顶优先级比较:
当前操作符 > OPTR栈顶,则进OPTR栈;当前操作符 ≤ OPTR栈顶,OVS栈顶、次顶和OPTR栈顶,退栈形成运算T(i), T(i)进OVS栈。
第一列为栈顶运算符,第一行为当前操作符。
算数四则运算的规则是1)先乘除,后加减;2)从左算到右;3)先括号内后括号外。 由此,算式4+23-10/5的计算顺序为4+23-10/5=4+6-10/5=4+6-2=8。 给定一个以“#”作为结束符的算式,求出算式的结果。
栈的问题还有很多,这里就不一一列举
下面栈的实现代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef int bool;
#define true 1
#define false 0
typedef struct Data
{
int nValve;
struct Data *pNext;
}Data;
typedef struct Stack
{
Data *pTop;
int nCount;
}Stack;
void PushStack(Stack *pTop,int elem);
int PopStack(Stack *pTop);
void Init(Stack **pTop);
void Clear(Stack *pStack);
Data *GetTop(Stack *pStack);
void Destroy(Stack **pStack);
int GetCount(Stack *pStack);
bool IsEmpty(Stack *pStack);
int main()
{
Stack *pStack = NULL;
//初始化栈指针
Init(&pStack);
// Destroy(&pStack);
PushStack(pStack,1);
PushStack(pStack,2);
PushStack(pStack,3);
PushStack(pStack,4);
PushStack(pStack,5);
printf("栈顶元素为%d\n",GetCount(pStack));
printf("%d\n",PopStack(pStack));
//Data *p = GetTop(pStack);
printf("GetCount = %d\n",GetCount(pStack));
//printf("GetTop = %d\n",p->nValve);
Clear(pStack);
if(IsEmpty(pStack) == true)
{
printf("栈为空\n");
}
else
printf("栈不为空\n");
printf("栈顶元素为%d\n",GetCount(pStack));
printf("%d\n",PopStack(pStack));
printf("栈顶元素为%d\n",GetCount(pStack));
printf("%d\n",PopStack(pStack));
printf("栈顶元素为%d\n",GetCount(pStack));
printf("%d\n",PopStack(pStack));
printf("栈顶元素为%d\n",GetCount(pStack));
printf("%d\n",PopStack(pStack));
return 0;
}
void Init(Stack **pStack)
{
//为栈顶指针申请空间
*pStack = (Stack*)malloc(sizeof(Stack));
(*pStack)->pTop = NULL;
(*pStack)->nCount = 0;
}
void PushStack(Stack *pStack,int elem)
{
//判断栈是否存在
if(pStack == NULL) exit(1);
//来一个元素,申请一块空间添加
Data *pNode = (Data*)malloc(sizeof(Data));
pNode->nValve = elem;
pNode->pNext = pStack->pTop;
pStack->pTop = pNode;
pStack->nCount++;
}
int PopStack(Stack *pStack)
{
//判断栈是否存在
if(pStack == NULL) exit(1);
//如果栈为空
if(pStack->pTop == NULL) return -1;
//删除栈顶元素并返回值
int elem = pStack->pTop->nValve;
Data *pDel = pStack->pTop;
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount--;
return elem;
}
void Clear(Stack *pStack)
{
//判断栈是否存在
if(pStack == NULL) exit(1);
while(pStack->pTop != NULL)
{
PopStack(pStack);
}
}
void Destroy(Stack **pStack)
{
//判断栈是否存在
if(*pStack == NULL) exit(1);
Clear(*pStack);
free(*pStack);
*pStack = NULL;
}
Data *GetTop(Stack *pStack)
{
//判断栈是否存在
if(pStack == NULL) exit(1);
return pStack->pTop;
}
int GetCount(Stack *pStack)
{
//判断栈是否存在
if(pStack == NULL) exit(1);
return pStack->nCount;
}
bool IsEmpty(Stack *pStack)
{
//判断栈是否存在
if(pStack == NULL) exit(1);
if(pStack->pTop == NULL)
return true;
else
return false;
}
上面就是栈的实现代码,如有错误,欢迎指正!