C语言栈的实现(顺序存储结构)
1.在定义的函数中改变主函数元素的值
首先,我们要先回顾一个知识,对于后面栈的学习会好理解点,如果我们在main()函数中定义了一个变量 int a; 需要在一个自定义的函数中改变其值,要怎么操作?
#include "stdio.h"
#include "stdlib.h"
int main(){
int add(int a);
int a=10;
a=add(a);
printf("%d",a);
}
int add(int a){
a=a+10;
return a;
}
我会首先想到这种方法,将改变后的值return回,但是在出栈的操作中,我们会遇到这种情况:我们需要将栈顶的元素返回,并将栈顶元素删除,此时可以说栈发生变化了,那我们在该Pop()函数返回时,应return哪一个,栈?还是栈顶的元素?
再看下面这个:
#include "stdio.h"
#include "stdlib.h"
int main(){
void add(int a);
int a=10;
add(a);
printf("%d",a);
return 0;
}
void add(int a){
a=a+10;
}
结果是10,如果不return,a值改变不了,但我们在出栈操作中要改变a的值,也就是要将栈顶的元素值赋给a。
看下面:
#include "stdio.h"
#include "stdlib.h"
void add(int *e){
*e=*e+20;
}
int main(){
void add(int *e);
int e=10;
add(&e);
printf("%d",e);
return 0;
}
返回值为30,e值在定义的函数中改变了,
add(&e);
将e的地址传入到了函数中,
*e=*e+20;
将地址中的值改变。
这样,在栈的实现时,经常会有这些操作,在理解上面的内容后,在实现栈时看到很多指针类型就不难理解了,这样就是为了在不return的情况下改变其内容。同样对栈也可以这样操作。
2. 栈的C语言实现
2.1 构建结构体
typedef int SElemType;
typedef struct{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间
}SqStack;
2.2 构造一个空栈
int InitStack(SqStack *s){
s->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s->base) exit(0); //存储分配失败
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return 1;
}
2.3 返回栈顶元素
int GetTop(SqStack s,SElemType *e){
if(s.top==s.base) return 0;
*e=*(s.top-1);
return 1;
}
注意,此时s前没有*,此函数操作时,栈不会发生改变。e会被赋上栈顶元素的值,也就是主函数中e的值会改变。
2.4 入栈
int Push(SqStack *s,SElemType e){
if(s->top-s->base>=s->stacksize){ //栈满,增加存储空间
s->base=(SElemType *)realloc(s->base,(s->stacksize+STACK_INIT_SIZE)*sizeof(SElemType));
if(!s->base) exit(0); //存储空间分配失败
s->top=s->base+s->stacksize;
s->stacksize+=STACKINCREMENT;
}
*(s->top++)=e;
return 1;
}
此处e为待插入元素。
2.5 出栈
int Pop(SqStack *s,SElemType *e){
if(s->top==s->base)
return 0;
*e=*--(s->top); //若栈不为空,用e返回其值
return 1;
}
此时需要返回栈顶元素,并且栈会发生改变,需要用到指针变量。e会被赋上栈顶元素的值。
3 整体代码
#include "stdio.h"
#include "stdlib.h"
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int SElemType;
typedef struct{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间
}SqStack;
int InitStack(SqStack *s){
s->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s->base) exit(0); //存储分配失败
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return 1;
}
int GetTop(SqStack s,SElemType *e){
if(s.top==s.base) return 0;
*e=*(s.top-1);
return 1;
}
int Push(SqStack *s,SElemType e){
if(s->top-s->base>=s->stacksize){
s->base=(SElemType *)realloc(s->base,(s->stacksize+STACK_INIT_SIZE)*sizeof(SElemType));
if(!s->base) exit(0);
s->top=s->base+s->stacksize;
s->stacksize+=STACKINCREMENT;
}
*(s->top++)=e;
return 1;
}
int Pop(SqStack *s,SElemType *e){
if(s->top==s->base)
return 0;
*e=*--(s->top); //若栈不为空,用e返回其值
return 1;
}
int main(){
SqStack S;
int e;
InitStack(&S);
Push(&S,10);
Push(&S,21);
GetTop(S,&e);
printf("%d",e);
Pop(&S,&e);
GetTop(S,&e);
printf("\n%d",e);
Pop(&S,&e);
printf("\n%d",e);
return 0;
}