关于栈
栈是一种常用的数据结构,使用栈可以对我们的编程带来很大的帮助,但前提是我们要了解栈的本质是什么。首先,我们要知道栈的特点是先进后出(或者说是后进先出),举个列子,就像餐厅里叠得很高的碗,当我们往碗层里放碗时,我们是放到碗层的最上方,而当我们拿碗时,我们也是从碗层的最上方拿碗。我们可以把栈设想成这个碗层,而这个过程在我们栈的数据结构里,放碗就对应于进栈的过程,而拿碗就相当于出栈的过程。
栈根据不同的存储方式可以分为两类。一类是顺序存储结构的顺序栈,另一类是链式存储结构的链栈。
一、顺序栈
1.定义
typedef struct{
ElemType *elem; //栈的存储数组,elem为数组名,*elem即栈的栈底元素
int top; //记录站顶元素的下一个位置,简称<strong>栈顶位标</strong>
int size; //当前分配的存储容量
int increment; //扩容时,增加的存储容量
}SqStack;
2.常用的接口
Status InitStack_Sq(SqStack &S, int size, int inc); //初始化顺序栈
Status DestroyStack_Sq(SqStack &S); //销毁顺序栈S
Status StackEmpty_Sq(SqStack S); //判断栈是否为空,若空返回TRUE,否则FALSE
void ClearStack_Sq(SqStack &S); //清空栈S
Status Push_Sq(SqStack &S, ElemType e); //元素e压入栈S
Status Pop_Sq(SqStack &S, ElemType e); //栈S的栈顶元素出栈,并用e返回
Status GetTop_Sq(SqStack S, ElemType &e); //取栈S的栈顶元素,并用e返回
3.接口的实现
/*初始化一个栈*/
Status InitStack_Sq(SqStack &S, int size, int inc){
S.elem = (ElemType*)malloc(size*sizeof(ElemType));
if(NULL==S.elem) return OVERFLOW;
S.top = 0;
S.size = size;
S.increment = inc;
return OK;
}
/*进栈操作*/
Status Push_Sq(SqStack &S, ElemType e){
ElemType *newbase; //栈的空间不足时,使用newbase指向一个空间更大的数组
if(S.top>=S.size){ //当栈满时
newbase = (ElemType *)realloc(S.elem, (S.size+S.increment)*sizeof(ElemType));
if(NULL==newbase) return OVERFLOW;
S.elem = newbase;
S.size = S.size + S.increment;
}
S.elem[S.top++] = e;
return OK;
}
/*出栈操作*/
Status Pop_Sq(SqStack &S, ElemType e){
if(S.top==0){
return ERROR;
}
e = S.elem[--S.top];
return OK;
}
/*栈的销毁*/
Status DestroyStack_Sq(SqStack &S){
if(S.top!=0){
free(S.elem);
//释放掉内存只是把申请的内存返还给系统
//还需要把指针设置为空
S.top = 0;
S.elem = NULL;
return OK;
}else return ERROR;
}
/*判断栈是否为空*/
Status StackEmpty_Sq(SqStack S){
if(S.top==0&&S.elem==NULL){
return TRUE;
}else return FALSE;
}
/*栈的清空*/
void ClearStack_Sq(SqStack &S){
//只要S.top设置为0即可
S.top = 0;
}
/*取栈顶元素*/
Status GetTop_Sq(SqStack S, ElemType &e){
if(S.top==0) return ERROR;
else{
e = S.elem[S.top-1];
}
return OK;
}
二、链栈
1.定义
typedef struct LSNode{
ElemType data; //数据域
struct LSNode *next; //指针域
}LSNode, *LStack; //结点和链栈类型
2.常用的接口
Status InitStack_LS(LStack &S); //初始化链栈S
Status DestroyStack_LS(LStack &S); //销毁链栈S
Status StackEmpty_LS(LStack S); //判断空栈,若栈S空则返回TRUE,否则FALSE
Status Push_LS(LStack &S, ElemType e); //元素e的压入栈S
Status Pop_LS(LStack &S, ElemType e); //栈S的栈顶元素出栈,并用e返回
Status GetTop_LS(LStack S, ElemType &e); //取栈S的栈顶元素,并用e返回
3.接口的实现
/*初始化一个链栈*/
Status InitStack_LS(LStack &S){
S = NULL;
}
/*进栈操作*/
Status Push_LS(LStack &S, ElemType e){
LSNode *t;
t = (LSNode*)malloc(sizeof(LSNode));
if(NULL==t) return OVERFLOW;
t->data = e;
t->next = S;
S = t;
return OK;
}
/*出栈操作*/
Status Pop_LS(LStack &S, ElemType e){
LSNode *t;
if(S==NULL) return ERROR;
t = S;
e = t->data;
S = S->next;
free(t);
return OK;
}
/*获得栈顶元素*/
Status GetTop_LS(LStack S, ElemType &e){
if(NULL==S) return ERROR;
else{
e = S->data;
return OK;
}
}
/*销毁一个栈*/
Status DestroyStack_LS(LStack &S){
LSNode *p,*q;
p = S;
q = S;
while(p!=NULL){
q = q->next;
free(p);
p = q;
}
S = NULL;
return OK;
}
/*判断栈是否为空*/
Status StackEmpty_LS(LStack S){
if(NULL==S) return TRUE;
else return FALSE;
}
以上接口的实现均是本人参考书本和网上资料,自己敲打出来的,错误肯定会有,所以希望有错误的地方大神们可以指出来,我会纠正的,至于其他一些接口,我会在需要或者想到的时候再补充,也欢迎大家帮我完善补充,对大家以后的学习都有帮助。