线性结构的两种常见应用之一 栈 (存储数据的结构)
定义
一种可以实现“先进后出” 的存储结构
栈类似于箱子
分类
静态栈 (类似于用数组实现)
动态栈 (类似于用链表实现)
算法(往里放,从里取)
出栈
压栈(参看Java中线程的例子,成产消费的例子)
//栈
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>//exit()
#include <string.h>
typedef struct Node
{
int data;
struct Node *pNext;
}NODE,*PNODE;
typedef struct stack
{
PNODE pTop;//栈头
PNODE pBottom;//栈底
}STACK,*PSTACK;
//函数声明
void init(PSTACK pS);//初始化栈
void push(PSTACK pS,int len);//压栈
void traverse(PSTACK pS);//遍历栈
bool is_empty(PSTACK pS);//判断是否为空
bool pop(PSTACK pS,int * pVal);//出栈
void clear(PSTACK pS);//清栈
//主函数入口
int main(void)
{
int len;
int val;
STACK S;//STACK 等价于struct Stack
init(&S);
printf("请输入您需要压栈的元素数目:");
scanf("%d",&len);
push(&S,len);
//遍历压栈后的结果
traverse(&S);
if(pop(&S,&val))
{
printf("出栈成功,且元素为:%d \n",val);
}else
{
printf("出栈不成功");
}
//遍历出栈后的结果
traverse(&S);
clear(&S);
//遍历清栈后的结果
traverse(&S);
return 0;
}
void init(PSTACK pS)//初始化栈
{
pS->pTop = (PNODE)malloc(sizeof(NODE));
if(NULL==pS->pTop)
{
printf("动态内存分配失败!\n");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
pS->pBottom->pNext = NULL;//pS->pTop->pNext = NULL;
}
}
void push(PSTACK pS,int len)
{
int val;
for(int i=0;i<len;i++)
{
printf("请输入您需要压栈的元素:");
scanf("%d",&val);
PNODE pNew = (PNODE)malloc(sizeof(NODE));
pNew->data = val;
pNew->pNext = pS->pTop;//pS->pTop表示pS所指向的栈中的pTop成员所指向的节点,其中pNext是指向pBottom方向的。
pS->pTop = pNew;
}
return;
}
bool is_empty(PSTACK pS)
{
if(pS->pTop == pS->pBottom)
return true;
else
return false;
}
void traverse(PSTACK pS)
{
PNODE p = pS->pTop;
//printf("栈顶元素:%d\n",pS->pTop->data);
if(is_empty(pS))
{
printf("栈为空!\n");
}
else
{
while (p != pS->pBottom)
{
printf("%d \n",p->data);
p=p->pNext;
}
}
return;
}
//把pS所指向的栈出栈一次,并且把出栈的元素存到pVal形参错指向的变量中
bool pop(PSTACK pS,int * pVal)
{
if( is_empty(pS))
{
return false;
}
else
{
PNODE r = pS->pTop;
*pVal = r->data;
pS->pTop = r->pNext;
free(r);
r=NULL;
return true;
}
}
void clear(PSTACK pS)
{
if( is_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;
}
}
应用
函数调用
中断
表达式求值(用两个栈,一个存放数字,一个存放符号)
内存分配
缓冲处理
迷宫
八进制转换
实现八进制
//八进制转换
#include <stdio.h>
#include <malloc.h>//malloc
#include <stdlib.h>//exit
#include <string.h>//scanf
typedef struct Node
{
int data;
struct Node *pNext;
}NODE,*PNODE;
typedef struct stack
{
PNODE pTop;//栈头
PNODE pBottom;//栈底
}STACK,*PSTACK;
//函数声明
void push(PSTACK pS,int num);//压栈
void init_stack(PSTACK pS);//初始化栈
void convert(PSTACK pS,int val);//八进制转换
void traverse(PSTACK pS);//遍历输出栈中的元素
//主函数
int main(void)
{
int val;//需要转换为八进制的数字
STACK S;
init_stack(&S);
printf("请输入您需要转换为八进制的数字:");
scanf("%d",&val);
convert(&S,val);
return 0;
}
void convert(PSTACK pS,int val)
{
while(val!=0)
{
push(pS,val%8);
val=val/8;
}
traverse(pS);
}
//初始化栈
void init_stack(PSTACK pS)//初始化栈
{
pS->pTop = (PNODE)malloc(sizeof(NODE));
if(NULL==pS->pTop)
{
printf("动态内存分配失败!\n");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
pS->pBottom->pNext = NULL;//pS->pTop->pNext = NULL;
}
}
//压栈
void push(PSTACK pS,int num)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
pNew->data = num;
pNew->pNext = pS->pTop;
pS->pTop = pNew;
return;
}
void traverse(PSTACK pS)
{
PNODE p = pS->pTop;
while (p != pS->pBottom)
{
printf("%d ",p->data);
p=p->pNext;
}
return;
}