#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int nValue;
struct node *pNext;
}MyStack;
typedef struct node2
{
MyStack *pTop;
int nCount;
}Stack;
void s_Init(Stack **pStack)
{
*pStack = (Stack *)malloc(sizeof(Stack));
(*pStack)->pTop = NULL;
(*pStack)->nCount = 0;
}
void s_Push(Stack *pStack,int nNum)
{
if(pStack == NULL)
{
printf("stack is not exist.\n");
return;
}
MyStack *pTemp = NULL;
pTemp = (MyStack*)malloc(sizeof(MyStack));
pTemp->nValue = nNum;
//新来节点的下一个是原来的栈顶
pTemp->pNext = pStack->pTop;
//新来节点成为新的栈顶
pStack->pTop = pTemp;
//计数器
pStack->nCount++;
}
int s_Pop(Stack *pStack)
{
if(pStack == NULL || pStack->pTop == NULL)return -1;
MyStack *pDel = NULL;
pDel = pStack->pTop;
int nNum;
nNum = pDel->nValue;
//原来栈顶的下一个成为新的栈顶
pStack->pTop = pStack->pTop->pNext;
free(pDel);
pDel = NULL;
pStack->nCount--;
return nNum;
}
void s_Clear(Stack *pStack)
{
if(pStack == NULL)return;
while(pStack->nCount != 0)
{
s_Pop(pStack);
}
}
void s_Destroy(Stack **pStack)
{
s_Clear(*pStack);
free(*pStack);
*pStack = NULL;
}
int s_GetCount(Stack *pStack)
{
if(pStack == NULL)return -1;
return pStack->nCount;
}
MyStack *s_GetTop(Stack *pStack)
{
if(pStack == NULL)
{
printf("stack is not exist.\n");
exit(1);
}
return pStack->pTop;
}
int s_IsEmpty(Stack *pStack)
{
if(pStack == NULL)return -1;
return pStack->nCount != 0 ? 0:1;
}
int main()
{
Stack *pStack = NULL;
s_Init(&pStack);
s_Push(pStack,1);
s_Push(pStack,2);
s_Push(pStack,3);
s_Push(pStack,4);
printf("%d\n",s_Pop(pStack));
printf("%d\n",s_Pop(pStack));
printf("%d\n",s_Pop(pStack));
printf("%d\n",s_Pop(pStack));
printf("%d\n",s_Pop(pStack));
s_Destroy(&pStack);
s_Push(pStack,2);
s_Push(pStack,3);
return 0;
}
以上代码有八种栈的基本操作:
1.初始化栈:我们所需要注意的就是 传参时应该传用二级指针 因为调用的函数修改了主函数中变量的值。
2.push操作:把元素添加到栈内,我理解的栈就是单项链表的尾添加尾删除
3 pop操作:删除栈未元素
4.clear清空栈内元素:实际上是把栈内元素删除,但是malloc
的空间并没有释放 ,与destroy不同
5.destroy操作:则是释放栈内的空间,整个栈所用的空间都被释放 注意这里传参也应用二级指针
6.GetCount :返回栈内元素的个数 ,在栈的结构体中有两个元素,一个是栈顶指针,另一个用来计数栈内元素的个数,在每进行push和pop的操作后,栈内计数的变量都要改变
7.Getpop: 返回栈顶元素
8.Isempty:判断栈是否为空。
栈的实际应用
四则运算:中缀和后缀
中缀转后缀的规则:(面试)
遇到数字和字母打印
遇到符号将当前符号与栈顶元素优先级比较
如果当前符号的优先级高则入栈
如果当前符号的优先级低,则栈里符号依次弹出栈元素,直到优先级低
遇到左括号无条件进栈,遇到右括号将栈内元素依次弹出直到左括号停止
简便算法(适用于做笔试题)
把所有运算可能的表达式用括号括起来,然后将运算符依次放到最近的括号后面,然后从左向右依次读取
后缀转中缀的规则
遇到数字或字母直接入栈,遇到符号将栈顶元素的下一个和栈顶元素构成表达式