数据结构---03---顺序栈---20205106009---郭睿玥
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | /*郭睿玥第三次算法实验作业*/ /*实验原理 栈是一种受限的线性表,由于规定了栈的入栈与出栈只能在一端进行,故而产生了后进先出, 先进后出的结果,因而常应用于具有这种特性的问题中进行模拟,广泛使用于程序设计中。 顺序栈是栈的顺序映像的实现,可采用静态顺序存储结构和动态存储结构,在静态顺序存储时 需分配一个预先设定大小的数组与栈顶指示器,规定若栈为空则栈顶指示器为-1,否则栈顶指示器 指向当前栈顶元素,栈满则栈顶指示器为预先设定的值减1,入栈时需栈顶指示器加1,此时元素入 栈即可,出栈时将当前栈顶指示器指向的元素返回,栈顶指示器减1即可。动态存储时需动态申请 预先设定的空间交给栈底指针,对栈操作时栈底指针不动,栈顶指针移动,为方便操作可将栈的长 度封装进来,动态实现的优点在于若空间不够时,可再申请一个增量的空间进行补充,但缺点是较 静态而言稍复杂一些。 */ /*实验环境 CodeBlocks*/ /*实验目的 掌握顺序栈的基本操作:初始化栈、判栈空、入栈、出栈、取栈顶数据元素等运算及程序实现方法。 */ /*实验内容 (1)定义栈的顺序存取结构。 (2)分别定义顺序栈的基本操作(初始化栈、判栈空、入栈、出栈等)。 (3)设计一个测试主函数进行测试。 (4)根据自己的理解添加更多的内容。 */ /*算法实现如下*/ # include <stdio.h> # include <malloc.h> # include <stdlib.h> #define STACK 5// 初始化栈的最大长度 #define STACKINCREMENT 3// 若栈最大空间不够时,需要增加的长度 typedef int Status; // 定义函数返回值类型 typedef int SElemType; // 定义每条数据的结构体类型 typedef struct { SElemType *top; // 栈顶指针 SElemType *bottom; // 栈底指针 SElemType stacksize; // 栈的最大长度 }stack; Status initstack(stack *s) { s->bottom=(SElemType*) malloc ( sizeof (SElemType)*STACK ); // 分配初始空间 if (!s->bottom) return 0; s->top=s->bottom; // 栈顶与栈底相同 s->stacksize=STACK; // 栈的最大长度等于初始长度 printf ( "创建成功\n" ); return 1; } Status push(stack *s,SElemType e) // 进栈,参数e是要进栈的元素 { // 若栈的最大长度不会够用时,重新开辟,增大长度 if (s->top-s->bottom>=s->stacksize) { s->bottom=(SElemType*) realloc (s->bottom, sizeof (SElemType)*(s->stacksize+ STACKINCREMENT)); if (!s->bottom) return 0; s->top=s->bottom+s->stacksize ; // 栈顶指针为栈底指针加上栈之前的最大长度 s->stacksize+=STACKINCREMENT; // 栈当前的最大长度等于栈之前的最大长度与增加的长度之和 } *s->top++=e; // 先赋值,后栈顶指针上移 return 1; } Status stackempty(stack *s) // 判断栈是否为空,只需要判断栈顶指针与栈底指针是否相同即可 { if (s->bottom==s->top) { printf ( "是空栈\n" ); return 1; } return 0; } void clearstack(stack *s) { if (!stackempty(s)) s->top = s->bottom; printf ( "清空成功\n" ); return 0; } Status DestroyStack(stack *s ) // 销毁栈,释放栈空间,栈顶栈底指针置为NULL,长度置为0 { free (s->bottom); s->stacksize = 0; s->bottom = s->top = NULL; printf ( "销毁成功\n" ); return 0; } Status pop(stack *s) // 出栈 { if (stackempty(s)) return 0; s->top--; return 1; } Status getop(stack*s) // 获取栈顶的元素,参数e用来存放栈顶的元素 { SElemType e; if (stackempty(s)) return 0; e=*(s->top-1); return e; } Status traverse(stack*s) // 遍历栈,依次打印每个元素 { if (stackempty(s)) return 0; SElemType * p; p=s->top; // 由栈顶依次向下遍历 while (p!=s->bottom) { p--; printf ( "%d" ,*p); printf ( "\n" ); } return 1; } int main() { stack S; int choice; do { /*显示操作界面*/ printf ( "***********************\n" ); printf ( "* 1. 构建空栈*\n" ); printf ( "* 2. 清空栈*\n" ); printf ( "* 3. 栈的判空*\n" ); printf ( "* 4. 压栈*\n" ); printf ( "* 5. 弹栈 *\n" ); printf ( "* 6. 获取栈顶元素\n" ); printf ( "* 7. 显示全部元素\n" ); printf ( "* 8. 销毁栈\n" ); printf ( "* 0. 退出。 *\n" ); printf ( "***********************\n" ); printf ( "\n" ); printf ( "请选择你要操作的选项:" ); scanf ( "%d" , &choice); //输入需要进行的选项 printf ( "\n" ); switch (choice) { case 1:{ initstack(&S); break ; } case 2:{ clearstack(&S); break ; } case 3:{ stackempty(&S); break ; } case 4:{ int i, n, f; printf ( "输入你想要入栈的元素个数:\n" ); scanf ( "%d" , &n); for (i = 1; i <= n; i++) { printf ( "请输入新一项" ); scanf ( "%d" , &f); push(&S, f); } break ; } case 5:{ pop(&S); break ; } case 6:{ printf ( "%d\n" ,getop(&S)); break ; } case 7:{ traverse(&S); break ; } case 8:{ DestroyStack(&S); break ; } case 0:{ printf ( "\n退出系统成功!请按任意键结束!\n" ); //退出程序 exit (0); } break ; } } while (choice); //只要选择不为需要进行的功能不为0则该程序可以一直进行下去 } /*以下是实验结果 操作界面如下 1. 构建空栈* 2. 清空栈* 3. 栈的判空* 4. 压栈* 5. 弹栈 6. 获取栈顶元素 7. 显示全部元素 8. 销毁栈 0. 退出。 郭睿玥 算法与数据结构第三次作业 (以下内容中操作界面的显示已经省略) 输入 请选择你要操作的选项:1 创建成功 请选择你要操作的选项:3 是空栈 请选择你要操作的选项:4 请输入你要入栈元素的个数;4 请输入新的一项;6 请输入新的一项7 请输入新的一项5 请输入新的一项9 请选择你要操作的选项:5 请选择你要操作的选项:6 5 请选择你要操作的选项:7 5 7 6 请选择你要操作的选项:2 清空成功 请选择你要操作的选项:8 销毁成功 请选择你要操作的选项:0 退出系统成功! */ |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通