栈
- 静态分配的变量在栈中分配内存
- 动态分配的变量在堆中分配内存
一、定义
一种可以实现“先进后出”的存储结构,栈类似于一个箱子
二、分类
1.静态栈:核心用数组实现
2.动态栈:核心用链表实现
三、算法
出栈
压栈(入栈)
四、应用
函数调用
中断
表达式求值(科学计算器)
内存分配
缓冲处理
迷宫
五、程序
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//节点的结构体
typedef struct Node
{
int data; //数据域
struct Node* pNext; //指针域
}NODE,*PNODE;
typedef struct Stack
{
PNODE top; //栈顶
PNODE bottom; //栈底
}STACK,*PSTACK;
//函数声明
void initStack(PSTACK); //初始化栈
PNODE createNode(); //创建一个新节点
void pushStack(PSTACK, int); //入栈
bool popStack(PSTACK); //出栈
bool popStackLevel(PSTACK, int*); //出栈(添加一个指针变量存放出栈的值的地址)
void display(PSTACK); //输出栈
void clearStack(PSTACK); //一键清空
//主函数
int main()
{
STACK stack; //创建一个栈
int val; //存放出栈的值
initStack(&stack); //初始化栈
printf("入栈的值为:");
pushStack(&stack, 1); //入栈1,2,3
pushStack(&stack, 2);
pushStack(&stack, 3);
display(&stack); //显示栈
popStackLevel(&stack, &val); //出栈,并显示出栈的值
printf("出栈的值为:%d ", val);
popStackLevel(&stack, &val);
printf("%d ", val);
popStackLevel(&stack, &val);
printf("%d \n", val);
printf("入栈的值为:");
pushStack(&stack, 1); //入栈1,2,3,4,5,6,7
pushStack(&stack, 2);
pushStack(&stack, 3);
pushStack(&stack, 4);
pushStack(&stack, 5);
pushStack(&stack, 6);
pushStack(&stack, 7);
display(&stack); //显示栈
printf("出栈后还剩的值为:");
popStack(&stack); //出栈7,6,5
popStack(&stack);
popStack(&stack);
display(&stack); //显示栈
printf("清空栈!");
clearStack(&stack); //一键清除
display(&stack); //显示栈
return 0;
}
//为新的节点分配内存
PNODE createNode()
{
PNODE pNew = (PNODE)malloc(sizeof(NODE)); //动态分配内存
if (pNew == NULL)
{
printf("节点内存分配失败!\n\n\n");
exit(-1);
}
pNew->pNext = NULL; //指针域指向NULL
return pNew; //将节点返回
}
//初始化栈
void initStack(PSTACK pStack)
{
pStack->top = createNode(); //为栈分配空间,栈顶和栈底指向同一节点说明栈为空,即初始化
pStack->bottom = pStack->top;
return;
}
//入栈
void pushStack(PSTACK pStack, int i)
{
PNODE pNEW = createNode(); //创建要入栈的节点
pNEW->pNext = pStack->top; //将新节点存到栈顶的位置
pNEW->data = i; //为新节点赋值
pStack->top = pNEW; //使栈顶始终指向最上面的节点
return;
}
//出栈
bool popStack(PSTACK pStack)
{
if (pStack->top != pStack->bottom)
{
PNODE pPop = pStack->top; //定义一个要指向出栈节点的游标指针,让其指向栈顶(先进后出,后进先出)
pStack->top = pStack->top->pNext; //更新栈顶位置
free(pPop); //释放出栈节点的空间
pPop = NULL;
return true;
}
else
{
printf("出栈失败,栈为空。");
return false;
}
}
//出栈(添加一个指针变量存放出栈的值的地址)
bool popStackLevel(PSTACK pStack, int * val)
{
if (pStack->top != pStack->bottom)
{
PNODE pPop= pStack->top; //定义一个要指向出栈节点的游标指针,让其指向栈顶(先进后出,后进先出)
pStack->top = pStack->top->pNext; //更新栈顶位置
*val = pPop->data; //保存出栈节点的数据域的值
free(pPop); //释放出栈节点的空间
pPop = NULL;
return true;
}
else
{
printf("出栈失败,栈为空。");
val = NULL;
return false;
}
}
//显示栈
void display(PSTACK pStack)
{
PNODE pPrint = pStack->top; //游标指针
while (pPrint != pStack->bottom) //当指向栈顶是说明保存有效数据的节点已经全部遍历完成
{
printf("%d ", pPrint->data); //输出节点数据
pPrint = pPrint->pNext; //指向下一个节点
}
printf("\n");
return;
}
//一键清空
void clearStack(PSTACK pStack)
{
PNODE pPop;
while (pStack->top != pStack->bottom)
{
pPop = pStack->top;
pStack->top = pStack->top->pNext;
free(pPop);
}
return;
}