栈之顺序栈
来源:互联网 发布:淘宝店标制作网站 编辑:程序博客网 时间:2024/05/22 11:41
目录
- 顺序栈的简介
- 举例以及详细分析
- 代码块
- 测试结果
顺序栈的简介
在顺序栈中有”上溢”和”下溢”的概念。顺序栈好比一个盒子,我们在里头放了一叠书,当我们要用书的话只能从第一本开始拿(你会把盒子翻过来吗?真聪明^^),那么当我们把书本放到这个栈中超过盒子的顶部时就放不下了(叠上去的不算,哼哼),这时就是”上溢”,”上溢”也就是栈顶指针指出栈的外面,显然是出错了。反之,当栈中已没有书时,我们再去拿,看看没书,把盒子拎起来看看盒底,还是没有,这就是”下溢”。”下溢”本身可以表示栈为空栈,因此可以用它来作为控制转移的条件。
举例以及详细分析
栈是仅限定在表尾进行插入和删除操作的线性表,共定义了九种栈的基本操作:分别是构造 销毁 清空 栈长 栈顶 插入 删除 遍历。
在下面压栈代码中,会用到realloc函数:void * realloc ( void * ptr, size_t new_size );
就是在原有内存上再申请一块内存!
关于realloc的行为方式,结合源码总结为:
1. realloc失败的时候,返回NULL;
realloc失败的时候,原来的内存不改变,也就是不free或不move,(这个地方很容易出错);
假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址;
如果size为0,效果等同于free();
传递给realloc的指针可以为空,等同于malloc;
传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的。
代码块
#include <stdio.h> #include<stdlib.h>#include <malloc.h>//int *p p只能是是地址 *p是值,指针是用来存储值的地址typedef int SElemType;typedef int Status;#define INIT_SIZE 100 #define STACKINCREMENT 10 #define Ok 1 #define Error 0 #define True 1 #define False 0 typedef struct{ SElemType *base; SElemType *top; int stacksize;}SqStack;//初始化栈 Status InitStack(SqStack *s){ s->base = (SElemType *)malloc(INIT_SIZE * sizeof(SElemType)); if (!s->base) { puts("存储空间分配失败!"); return Error; } s->top = s->base; s->stacksize = INIT_SIZE; return Ok;}//清空栈 Status ClearStack(SqStack *s){ s->top = s->base; return Ok;}//栈是否为空 Status StackEmpty(SqStack *s){ if (s->top == s->base) return True; else return False;}//销毁栈 Status Destroy(SqStack *s){ free(s->base); s->base = NULL; s->top = NULL; s->stacksize = 0; return Ok;}//获得栈顶元素 //Status GetTop(SqStack *s, SElemType &e)//{// if (s->top == s->base) return Error;// e = *(s->top - 1);// return Ok;//}//压栈 Status Push(SqStack *s, SElemType e){ if (s->top - s->base >= s->stacksize)//栈满 { s->base = (SElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElemType)); //这次申请的内存是以s->base为起始点的内存,但是s->base的位置有可能发生变化,这里是多分配了STACKINCREMENT个SElemType if (!s->base) { puts("存储空间分配失败!"); return Error; } s->top = s->base + s->stacksize;//修改栈顶位置 s->stacksize += STACKINCREMENT;//修改栈长度 } *s->top++ = e; return Ok;}//弹栈 Status Pop(SqStack *s, SElemType *e){ if (s->top == s->base) return Error; s->top--;//因为在插入的时候为*s->top++=e,最后一次入栈完成后,top指针还会加1,最后top指针指向的并不是栈顶元素而是栈顶元素上面的空间,因此要-- *e = *(s->top); return Ok;}//遍历栈 Status StackTraverse(SqStack *s){ SElemType *b = s->base;//此处不能直接用base或top移动,即不能改变原栈的结构 SElemType *t = s->top; while (t > b) printf("%d ", *b++); printf("\n"); return Ok;}//Status visit(SElemType c)//{// printf("%d ", c);// return Ok;//}int main(){ SqStack a; SqStack *s = &a; SElemType e; InitStack(s); int n; puts("请输入要进栈的个数:"); scanf("%d", &n); while (n--) { int m; scanf("%d", &m); Push(s, m); } /*e = GetTop(s, e);*/ StackTraverse(s); puts(""); puts("8进栈后:"); Push(s, 8); StackTraverse(s); puts(""); Pop(s, &e); printf("出栈的元素是:%d\n", e); printf("元素出栈后事实上并没有清除,依然存在于内存空间,所谓的出栈只是指针移动,出栈的元素是%d\n", *s->top);//判断出栈后元素是否还存在于内存中 StackTraverse(s); Destroy(s); system("pause"); return 0;}
测试结果
- 栈之顺序栈
- 栈之顺序栈
- 栈之顺序栈
- 栈之顺序栈
- 栈之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- 数据结构之顺序栈
- DS之顺序栈
- 数据结构之顺序栈
- C#之顺序栈
- 栈之顺序实现
- 数据结构之顺序栈
- 第十七篇:桥接模式
- Mycat概述
- B1038. 统计同成绩学生(20)
- 算法设计与应用基础-第五周
- 待解决:selenium 未能获取alert!记录,期待大家指导!
- 栈之顺序栈
- 线性表介绍
- UIControl介绍以及Target-Action机制
- Unity 游戏存档 PlayerPrefs类的用法
- Leetcode 62. Unique Paths
- 新创建的iOS项目Cocoapods导入AFNetworking报错:AFNetworking.framework/AFNetworking' does not contain bitcode. Yo
- Android DataBinding入门篇
- Git之忽略文件(ignore file)
- maven中的groupId和artifactId到底指的是什么?