郝斌数据结构入门---P30---栈
线性结构的常见应用之一:栈(只能头部插入,头部删除)
定义:一种可以实现“ 先进后出 ”的存储结构,栈类似于箱子
分类:静态栈,动态栈
算法:出栈pop,入栈push(压栈)
应用:函数调用,中断,表达式求值,内存分配,缓冲处理,迷宫
为了便于链表的操作,产生一个没有实际含义的头结点。
扫描二维码关注公众号,回复:
3819868 查看本文章
初始化栈init()函数:
建立一个空栈,把pTop和pBotoom都指向头结点
压栈push()函数:
第一步:先创建一个新的节点
第二步:把val赋给新节点的数据域
第三步:因为每次压栈到当前栈顶的上方,所以把新节点的指针域指向pTop
第四步:pTop指向新的节点
遍历输出traverse()函数:
定义一个指针p,p永远指向栈顶元素
然后从栈顶到栈底依次遍历
出栈pop()函数:
把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中
如果出栈失败,返回-1,否则返回1
先定义指针r,然后再把pTop往后移一个,最后把r释放
清空节点clear()函数:
定义两个指针p和q
p指向栈顶元素,q指向栈顶下一个元素
这样释放p,q刚好是下一个元素,然后再把q赋值给p,q往下移一个
代码如下:
//动态栈的本质是操作链表
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
//NODE = struct Node
//PNODE = struct Node *
typedef struct Node
{
int data;
struct Node * pNext;
}NODE, *PNODE;
//STACK = struct Stack
//PSTACK = struct Satck *
//栈里面有两个元素pTop,pBottom
typedef struct Stack
{
PNODE pTop; //指向栈的顶部
PNODE pBottom; //指向栈的底部
}STACK, *PSTACK; //PSTACK 等价于 struct Stack *
void init(PSTACK);
void push(PSTACK, int);
void traverse(PSTACK);
int pop(PSTACK, int *);
void clear(PSTACK pS);
int main(void)
{
STACK S; //STACK 等价于 struct Stack
int val; //保存出栈的元素
init(&S);//初始化栈,目的是造出一个空栈
push(&S, 1);//压栈
push(&S, 2);//压栈
push(&S, 3);//压栈
push(&S, 4);//压栈
push(&S, 5);//压栈
push(&S, 6);//压栈
traverse(&S);//遍历输出
clear(&S);//清空节点
traverse(&S);//遍历输出
if (pop(&S, &val))//出栈
{
printf("出栈成功,出栈的元素是%d\n", val);
}
else
{
printf("出栈失败!\n");
}
traverse(&S);//遍历输出
return 0;
}
//初始化目的:建立一个空栈,把pTop和pBotoom都指向头结点
void init(PSTACK pS)
{
pS->pTop = (PNODE)malloc(sizeof(NODE));
if (NULL == pS->pTop)
{
printf("动态内存分配失败!\n");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
pS->pTop->pNext = NULL; //pS->pBottom->pNext = NULL;
}
}
//压栈
//第一步:先创建一个新的节点
//第二步:把val赋给新节点的数据域
//第三步:因为每次压栈到当前栈顶的上方,所以把新节点的指针域指向pTop
//第四步:pTop指向新的节点
void push(PSTACK pS, int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建新的节点
pNew->data = val; //把val赋给新节点的数据域
pNew->pNext = pS->pTop; //pS->pTop不能改成pS->Bottom
pS->pTop = pNew;
return ;
}
//遍历输出
//定义一个指针p,p永远指向栈顶元素
//然后从栈顶到栈底依次遍历
void traverse(PSTACK pS)
{
PNODE p = pS->pTop;
while (p != pS->pBottom)
{
printf("%d ", p->data);
p = p->pNext;
}
printf("\n");
return;
}
//判断栈是否为空
int empty(PSTACK pS)
{
if (pS->pTop == pS->pBottom)
return 1;
else
return 0;
}
//出栈
//把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中
//如果出栈失败,返回-1,否则返回1
//先定义指针r,然后再把pTop往后移一个,最后把r释放
int pop(PSTACK pS, int *pVal)
{
if (empty(pS)) //pS本身存放的就是S的地址
{
return 0;
}
else//栈是非空
{
PNODE r = pS->pTop;
*pVal = r->data;//保存栈顶数据
pS->pTop = r->pNext;
free(r);
r = NULL;
return 1;
}
}
//clear 清空节点
//定义两个指针p和q
//p指向栈顶元素,q指向栈顶下一个元素
//这样释放p,q刚好是下一个元素,然后再把q赋值给p,q往下移一个
void clear(PSTACK pS)
{
if (empty(pS))//空的时候,不需要操作
{
return;
}
else //非空的时候,才需要操作
{
PNODE p = pS->pTop;
PNODE q = NULL;
while (p != pS->pBottom)//不是最后一个元素
{
q = p->pNext;
free(p);
p = q;
}
pS->pTop = pS->pBottom;
}
}