栈 定义及基本操作
栈 是一个线性表,插入和删除位置限制在线性表的尾部进行要插入X,只能插入在最后一个元素的后面,也只能删除最后一个元素
栈是插入和删除受到限制的线性表
通常将允许删除,插入操作的一端称为栈顶,另一端称为栈底
不含任何一个元素的栈称为空栈 。
栈是一种先进后出(Last IN First Out)的线性表,简称LIFO
栈的插入操作被形象的称为进栈,或入栈(压栈)
删除操作被称为出栈,或退栈(弹出)
栈首先的一个线性表,它的特殊之处在于限制了插入和删除的位置
始终只能在栈顶执行
这使栈底是固定的,最先插入的只能在栈底,最后放入的元素在栈顶
删除元素恰好相反,最后放入的元素最先删除,最先放入的元素最后删除
栈的操作特点就是"先进后出"其基本操作除了在顶部插入删除元素还有栈的初始化,判空及取栈顶元素
- 栈初始化 Init_Stack(S) 构造一个空栈
- 判空 Empty_Stack(S)若栈S为空,返回0,不为空,返回1
- 入栈 Push_Stack(S,X) 判断栈S是否栈满,如果栈满,不能入栈,未满则在栈顶插入元素X
- 出栈 Pop_Stack(S) 判断栈S 是否为空栈,如果是空,不能出栈,不为空,栈顶元素
- 读栈顶元素 Top_Stack(S) 栈顶元素作为返回结果
栈–函数调用中的应用
当函数调用另一个函数是,运行被调用前,系统需经过以下几步:
- 为函数参数及控制信息(返回地址),在栈内存中申请空间,专递实参
- 为被调用函数的局部变量在栈中分配空间
- 控制转到被调任的程序入口
被调用函数返回到调用函数之前
- 保存结构
- 释放被调用函数的数据区
- 依照被调用保存的控制信息(返回地址)返回
main()
{
int m ,n;
first(m,n);
0;
}
void first(int x,int y)
{
char i;
second(i);
1;
}
void second(char d)
{
int x,y;
0;
}
入栈:
- 先执行main() ,并在栈内存空间开辟 m n
- 再执行first(),在栈内存空间开辟 x y i
- 最后执行second() 在内存控制开辟d x y
出栈
- List item执行second() 保存结果释放空间,依照记录的返回地址,返回调用,继续执行
- 在执行first() 保存结果释放, 依照记录的返回地址 返回调用,继续执行
- main() 执行结束,保存结构释放空间,此栈为空,程序执行结束
栈的存储结构 --顺序栈
栈本身就是 一个线性表,线性表的两种存储结构,同样试用栈
类似于,顺序表的定义
#define MAXSIZE 100
typedef struct
{
datatype data[MAXSIZE];
int top;
} SeqStack
栈中的数据元素用一个预设的足够大的一维数组data来存储数据
栈插入,删除在线性表的一端,线性表顺序存储结构中的last位置可以作为插入删除的一端,也就是栈顶,这用Top表示栈顶的位置,下标为0表示栈底
- 定义一个指向顺序栈的指针 SeqStack *S;
- 0下标段设为栈底,空栈时,栈顶指针 S->top = -1
- 入栈时,栈顶指针加 1,即S->top++
- 将待插入元素X放入栈中S->data[S->top]=x;
- 出栈时,将栈顶元素记出x=S->data[s-top]
- 栈顶指针减一 即,S->top --;
注意事项
对于顺序栈,入栈时,首先判断栈是否满了,栈满的条件为:
S->Top==MAXSIZE, 栈满时,不能入栈,否则出栈时空间溢出,引起错误,称为上溢
出栈和读栈顶元素操作,先判断栈是否为空,为空不能读栈不能出栈,否则产生下溢
栈的存储结构–链 栈
用链式存储结构实现的栈,为链栈,通常链栈用单链表来表示其节点结构与单链表的结果相同
typedef struct node
{
datatype data;
struct node *next;
}StackNode, *LinkStackptr;
用LinkStackptr 说明一个变量top作为链栈的栈顶指针LinkStackptr top
用一个计数器来记录链栈中数据元素个数 int count
将Top count 放在结构体中,形成栈的存储结构
typedef struct LinkStack
{
LinkStackptr top;栈顶
int count; 栈中元素个数
}LinkStack;
对于链栈来说,不设头结点,栈中的主要运算是在栈顶插入删除元素,平常的单链表常用的头结点也失去了意义
- 设LinkStack *S; 对于空栈,头指针为空,即S->top =Null
S->Top指向栈顶,栈底的指针域为空
链栈基本不存在栈满的情况,除非内存已经没有可使用的空间 - 从空栈开始入栈
S->top =null
指针指向待入栈顶结点
将结点的后继指针指向栈顶指针S->top
即P->next = S->top;
再将S->top 指向p S->top =p
链栈的出栈
栈不为空,用一个指针P指向当前栈顶 P=S->top
栈顶指针下移,S->Top=(s->top)->next;
记出 P的数据部分
x=(S-top)->data;
释放 p free(p )
最后栈中元素个数减一;