顺序栈的入栈与出栈-----(c语言)

栈:是限定仅在表尾进行插入和删除操作的线性表(顺序结构)

栈顶:允许插入跟删除的一端

栈底:固定的一端,不允许在栈底进行插入跟删除

入栈:栈的插入操作

出栈:栈的删除操作


目录

定义栈

创建空栈

 入栈

 出栈

 源代码


定义栈


#include
#include
#define ok 1
#define error 0
#define sizemax 10
typedef int ElemType;typedef struct {ElemType *base;//栈底ElemType *top;//栈顶int sizestack;//分配栈的值
}Sqstack;//定义栈

此处定义栈的最大值为10,当然如果需要后续分配更大的内存空间,可以使用realloc函数增加新的空间(作者还没学会使用)。


创建空栈

int initstack(Sqstack* s) {s->base = (ElemType*)malloc(sizeof(ElemType) * SIZEMAX);//给base分配内存空间,返回base的首地址if (!s->base) {return error;}s->top = s->base;//出发点为base的首地址,栈顶从底地址开始s->sizestack = SIZEMAX;//最大空间return ok;
}//创建空栈

创建空栈,就需要给栈底分配一块内存空间,将栈底的首地址返回,就可以通过栈底首地址对栈进行修改。所以将栈底的首地址赋值给栈底(s->top),就可以对栈底进行修改了。

图解:

值得注意的是,栈底的首地址不一定是从0开始的,而是这里为了方便图片的展示而写成0。由于用了malloc函数,编译器给s->base的地址是随机分配的,如果需要查看真正的地址,可以调试监控窗口查看。


 入栈

int push(Sqstack* s, ElemType e) {if (s->top - s->base == SIZEMAX ) {printf("栈满,无法入栈\n");return error;}*(s->top) = e;//(由于s是指针,想要将里面的值赋值,需要带上*号)s->top++;return ok;
}//入栈

入栈前首先要判断栈是否满了,这里可以用s->top-s->base的值判断是否满了(地址的分配原理),将输入的值赋值给栈顶,用指针对地址里面的值修改,必须要用上星号(指针的原理)。那么问题就来了,是先插入在进行栈顶指针的自增呢,还是先栈顶指针自增在插入呢?动动小脑袋瓜来思考一下,在定义栈的时候,博主将栈底的地址赋值给栈顶指针,入栈时,将e的值赋值给此处栈顶指针,如果先进行指针自增,那么执行到插入时,他后面的那一个空栈就会跳过了,此时插入的空间是自增后的那个空间,造成空间浪费,不理解的同学可以上机实践,看看调换这个语句的顺序会发生什么。

 正确的做法是先插入,栈顶指针在自增。


 出栈

int pop(Sqstack* s, ElemType *e) {if (s->top == s->base) {return error;}s->top--;//先--是因为输入的最后一个值是非整形的,需要忽略非整形的字符*e = *(s->top);return ok; 
}//出栈

出栈前要判断栈是否为空,判断条件是s->top=s->base                                                                     在动动小脑瓜思考,这里为什么又要先栈顶指针自减在赋值给*e,这就涉及到另一个模块的代码了

int creatstack(Sqstack* s) {int e;if (initstack(s)) {printf("栈创建成功!\n");}else {printf("栈创建失败\n");return error;}printf("请输入数据\n");while (scanf("%d", &e)) push(s, e);return ok;
}//创建并输入

在这个函数中,我们调用创建栈的函数,创建成功后进行入栈操作

while (scanf("%d", &e)) push(s, e);

我们使用scanf输入要入栈的值,由于我们定义的是整形,输入的也是整形,这里介绍一下scanf的返回值,是成功读入参数的个数,我们都知道,判定条件,0为假,非0为真。当输入多组整数时,按下回车后,这些整数会进入缓冲区中,然后scanf函数会一个个读取缓冲区中的数据,当读取到一个整数时返回值是1,当读到非整数的值时,返回值是0,因此在while中,想要让这个输入循环停止,就要输入一个非整数的值,比如字母a,但是在入栈的时候,输入非整数的值仍然会保持在栈中,因此在出栈中,要错开这个值,所以在出栈函数中,首先要栈顶指针先自减,在将栈存储的值赋值给指针*e。

如果先赋值在自减出栈时就会造成如下错误:

 输出了非整数的值,并且还造成了栈里面的内容丢失

 正确操作是先自减在赋值:

 图解:


 源代码


#include
#include
#define ok 1
#define error 0
#define SIZEMAX 10
typedef int ElemType;typedef struct {ElemType *base;//栈底ElemType *top;//栈顶int sizestack;//分配栈的值
}Sqstack;//定义栈int initstack(Sqstack* s) {s->base = (ElemType*)malloc(sizeof(ElemType) * SIZEMAX);//给base分配内存空间,返回base的首地址if (!s->base) {return error;}s->top = s->base;//出发点为base的首地址,栈顶从底地址开始s->sizestack = SIZEMAX;//最大空间return ok;
}//创建空栈int push(Sqstack* s, ElemType e) {if (s->top - s->base == SIZEMAX ) {printf("栈满,无法入栈\n");return error;}*(s->top) = e;//(由于s是指针,想要将里面的值赋值,需要带上*号)s->top++;return ok;
}//入栈int pop(Sqstack* s, ElemType *e) {if (s->top == s->base) {return error;}s->top--;//先--是因为输入的最后一个值是非整形的,需要忽略非整形的字符*e = *(s->top);return ok; 
}//出栈int creatstack(Sqstack* s) {int e;if (initstack(s)) {printf("栈创建成功!\n");}else {printf("栈创建失败\n");return error;}printf("请输入数据\n");while (scanf("%d", &e)) push(s, e);return ok;
}//创建并输入int printstack(Sqstack* s) {ElemType e;while (pop(s, &e)) printf("%3d", e);return ok;
}//出栈并且输出int main() {Sqstack s;printf("创建并输出\n");creatstack(&s);printf("出栈并且输出\n");printstack(&s);return 0;
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部