栈是一种只能在一端进行插入或删除操作的线性表。其中允许进行插入或删除操作的一端称为栈顶。栈顶由一个称为栈顶指针的位置指示器来指示,它是 动态变化的。表的另一端称为栈底,栈底是固定不变的。栈的插入和删除操作一般称为入栈和出栈。
栈的存储结构
可用顺序表和链表来存储栈,栈可以依照存储结构分为两种;顺序栈和链式栈。在栈的定义中已经
说明,栈是一种在操作上稍加限制的线性表,即栈本质上是线性表,而线性表有两种主要的存储结构——
顺序表和链表,因此栈也同样有对应的两种存储结构。
顺序栈定义
typedef struct{
int data[maxsize];//存放栈中元素,maxsize是已定义的最大常量
int top;//栈顶指针
}sqstack;
链栈结点定义
typedef struct lnode{
int data;//数据域
struct lnode *next;//指针域
}lnode;
链栈就是采用链表来存储栈。这里用带头结点的单链表来作为存储体
顺序栈
1.顺序栈的要素
对于顺序栈,一共有4个要素,包括两个特殊状态和两个操作。
两个状态
1.栈空状态。
st.top=-1。有的规定 st.top=0为栈空条件,这样会浪费一个元素大小的空间
2.栈满状态。
st.top=maxSize-1。maxSize为栈中最大元素的个数,则maxSize-1为栈满时栈顶元素在数组中的位置
非法状态(上溢和下滥)
栈满继续入栈就会上溢的状态,对应的栈下溢就是栈空时继续出栈所造成的结果。
两个操作
1.元素x进栈操作
2.元素x出栈操作
2.初始化栈代码
void initstack(sqstack &st){//初始化栈
st.top=-1;//只需将栈顶指针设置为-1
}
3.判断栈空代码
int isempty(sqstack st){
if(st.top==-1)
return 1;
else
return 0;
}
4.进栈代码
int push(sqstack &st,int x){
if(st.top==maxsize-1)//这里要注意栈满不能入栈
return 0;
++(st.top);//先移动指针再入栈
st.data[at.top]=x;
return 1;
}
5.出栈代码
int pop(sqstack &st,int &x){
if(at.top==-1){//注意如果栈空则不能出栈
return 0;
}
x=at.data[at.top];//先取出元素再移动指针
--(st.top);
return 1;
}
链栈
1.链栈的要素
和顺序栈对应,链栈也有4个要素,包括两个特殊状态和两个操作。
两个状态
1.栈空状态
List->next==NULL
2.栈满状态
不存在
两个操作
1.进栈操作
2.出栈操作
2.栈链的初始化代码
void initstack(lnode*&lst){//lst要改变用引用型
lst=lnode*malloc(sizeof(lnode));//创造一个头节点
lst->nect==NULL;
}
3.判断栈空代码
int isempty(lnode *lst){
if(lst->next==NULL){
return 1;
}
else
return 0;
}
4.进栈操作代码
void push(lnode *lst,int n){
lnode *p;
p=(lnode*)malloc(sizeof(lnode));//为进栈元素申请节点空间
p->next==NULL;
p->data=x;
p->next=lst->next;
lst->next=p;
}
5.出栈操作代码
int pop(lnode *lst,int &x){//需要改变的变量要用引用型
lnode *p;
if(lst->next==NULL){
return 0;
}
p=lst->next;
x=p->data;
lst->next=p->next;
free(p);
return 1;
}
熟悉栈常规操作将利于后面算法学习的进行,我是sejun,关注学习更多知识。