数据结构学习(C语言)-栈的基本操作
1、栈的定义
栈就是一种可以实现“先进后出”的存储结构。换句话说,栈的存储结构就像是向一个箱子里放书,后放进去的只能放在前面的上面,而且后放进去的可以直接拿出来,而先放进去的就必须等否放进去的拿出后才能拿出来。
2、栈的分类
栈主要分为静态栈和动态栈两种。
3、栈的核心算法
栈最核心的两步操作是压栈(进栈)和出栈。
4、栈的应用
栈的主要应用有函数调用,中断,表达式求值(计算器实现),内存分配,缓冲处理,迷宫等。
5、栈的基本操作代码
#include<stdio.h>
#include<stdlib.h>
typedef struct NODE {
int data;
struct NODE * pNext;
}node,*pNode;
typedef struct STACK {
pNode pTop;
pNode pButtom;
}stack,*pStack;
void initStack(pStack pS);//初始化(创建一个没有实际意义的头结点)
void pushStack(pStack pS, int val);//压栈(进栈/追加数据)
void traverseStack(pStack);//遍历(输出栈中所有元素,遍历的顺序为由上到下)
bool popStack(pStack, int *);//出栈(相当于删除栈顶元素)
bool isEmpty(pStack);//判断栈是否为空
void getNum(pStack);//获取栈中元素(结点)个数
void clearStack(pStack);//将栈中元素(结点)清空
int main(void) {
stack S;//定义一个stack结构体变量
int val;
initStack(&S);//初始化
pushStack(&S, 1);//压栈(进栈)
pushStack(&S, 2);
pushStack(&S, 3);
pushStack(&S, 4);
pushStack(&S, 5);
pushStack(&S, 6);
traverseStack(&S);//遍历栈中元素
popStack(&S,&val);//出栈
traverseStack(&S);//遍历(出栈结果验证)
getNum(&S);//栈长(结点数)
clearStack(&S);//清空栈
if (isEmpty(&S)) {
printf_s("---栈空---\n");
}//验证清空结果1
getNum(&S);//验证清空结果2
return 0;
}
void initStack(pStack pS) {// 初始化
pS->pTop = (pNode)malloc(sizeof(node));//申请一个结点,pTop指向这个结点
if (pS->pTop == NULL) {//可能会申请失败
printf_s("动态内存分配失败!\n");
exit(-1);
}
else{
pS->pButtom = pS->pTop;//此时只有这一个无实际意义的结点,pB和pT都指向它
pS->pTop->pNext = NULL;//将这个无实际意义的结点指向空
}
return;
}
void pushStack(pStack pS, int val) {//压栈
pNode pNew = (pNode)malloc(sizeof(node));//申请分配一个新结点
pNew->data = val;//给新结点赋值
pNew->pNext = pS->pTop;
pS->pTop = pNew;
return;
}
void traverseStack(pStack pS) {//遍历
pNode p = pS->pTop;
while (p != pS->pButtom) {
printf_s("%d ", p->data);
p = p->pNext;
}
printf_s("\n");
return;
}
bool isEmpty(pStack pS) {//栈是否空
if (pS->pTop == pS->pButtom) {
return true;
}
else
return false;
}
bool popStack(pStack pS , int *val) {//出栈
if (isEmpty(pS)) {//判断栈是否为空
printf_s("栈为空!出栈失败!\n");
return false;
}
else {
pNode p = pS->pTop;
pS->pTop = p->pNext;
*val = p->data;
free(p);
p->pNext = NULL;//防止野指针
printf_s("栈顶元素:%d 已出栈!\n", *val);
return true;
}
}
void getNum(pStack pS) {//求栈长
if (isEmpty(pS)) {
printf_s("栈长为:0\n");
}
else {
pNode p = pS->pTop;
int n = 0;
while (p != pS->pButtom) {
n++;
p = p->pNext;
}
printf_s("栈长为:%d\n", n);
}
return;
}
void clearStack(pStack pS) {//清空栈
if (isEmpty(pS)) {
printf_s("栈已空,无需在清空!\n");
}
else {
pNode p = pS->pTop;
pNode q = NULL;
while (p != pS->pButtom) {
q = p->pNext;
free(p);
p = q;//释放p,再将p指向q(即下一个结点),无需担心野指针
}
pS->pTop = pS->pButtom;
printf_s("清空成功!\n");
}
return;
}
6、代码运行结果