实验内容:
实验4、顺序栈的基本操作及应用
(1)实验目的
通过该实验,让学生掌握栈的相关基本概念,认识栈是插入和删除集中在一端进行的线性结构,掌握栈的“先入后出”操作特点。栈在进行各类操作时,栈底指针固定不动,掌握栈空、栈满的判断条件。
(2)实验内容
用顺序存储结构,实现教材定义的栈的基本操作,提供数制转换功能,将输入的十进制整数转换成二进制、八进制或十六进制。
(3)参考界面
菜单中包括以下功能:
1.初始化栈,2.销毁栈,3.清空栈,4.栈判空,5.求栈长度,6.获取栈顶元素,7.插入一个 元素,8.删除一个元素,9输出所有元素,10进制转换。
要求:自定义的函数中不允许出现提示语和输出语句。
(4)验收/测试用例
通过菜单调用各个操作,测试点:
l 没有初始化前进行其他操作,程序是否能控制住;
l 初始化一个栈;
l 判栈空,屏幕显示栈为空;
l 3个数入栈, 2、4、6;
l 栈长度,屏幕输出3;
l 取栈顶元素,再判栈空,然后再判栈长度。让学生知道取栈顶元素不改变栈中的内容,栈顶指针不发生改变;
l 出栈,再判栈长度和输出栈中内容;(多次出栈,直到栈为空;再出栈,是否提示栈为空)
l 销毁栈,再做其他操作,判断程序是否能控制;
数制转换,(允许用户输入想把十进制转换成几进制),然后灵活的转换成对应的进制。
实验环境:
VS2019
设计思想
1.设置主函数类main.cpp进行菜单的展示和执行,设置头文件stuck.h存放函数和构造体声明,设置功能函数类stuck.cpp存放功能函数;
2.每个函数调用前判断栈是否初始化,个别函数之后仍需判断栈是否为空;
3.菜单展示和执行使用while循环,每次循环前进行清屏,提高用户体验;
4.进制转换:
可以进行十以内进制包括十六进制的转换,在进行十六进制转换输出时,判断元素>9则输出相应的字母,否则直接输出;程序使用过后释放内存; 增加对输入数为0的判断;
5.直接退出程序先调用销毁函数释放内存空间;
二、主要源代码
main.cpp
1 #include "stack.h" //引入自定义头文件 2 int main() 3 { 4 Stuck stuck; 5 stuck.base = NULL; 6 Stuck trans_stuck; //进制转换所需栈 7 trans_stuck.base = NULL; 8 int position; 9 while (true) 10 { 11 system("cls"); 12 cout << "欢迎使用本程序" << endl; 13 cout << "1. 初始化栈" << endl; 14 cout << "2. 销毁栈" << endl; 15 cout << "3. 清空栈" << endl; 16 cout << "4. 栈判空" << endl; 17 cout << "5. 求栈长度" << endl; 18 cout << "6. 获取栈顶元素" << endl; 19 cout << "7. 插入一个元素" << endl; 20 cout << "8. 删除一个元素" << endl; 21 cout << "9. 输出所有的元素" << endl; 22 cout << "10.进制转换" << endl; 23 cout << "请输入指令完成操作" << endl; 24 cin >> position; 25 if (position < 0) 26 { 27 cout << "谢谢您的使用" << endl; 28 destoryStuck(stuck); //结束时释放栈内存空间 29 break; 30 } 31 switch (position) 32 { 33 case 1: 34 if (stuck.base) 35 { 36 cout << "请进行销毁操作后再初始化" << endl; 37 } 38 else 39 { 40 initializeStuck(stuck); 41 if (stuck.base) 42 cout << "初始化成功" << endl; 43 else 44 cout << "初始化失败" << endl; 45 } 46 system("pause"); break; 47 case 2: 48 if (stuck.base) 49 { 50 destoryStuck(stuck); 51 if (stuck.base) 52 cout << "销毁失败" << endl; 53 else 54 cout << "销毁成功" << endl; 55 } 56 else 57 { 58 cout << "请初始化后再进行销毁" << endl; 59 } 60 system("pause"); break; 61 case 3: 62 if (stuck.base) 63 { 64 emptyStuck(stuck); 65 if (ifEmpty(stuck)) 66 cout << "清空失败" << endl; 67 else 68 cout << "清空成功" << endl; 69 } 70 else 71 { 72 cout << "请初始化后再进行清空操作" << endl; 73 } 74 system("pause"); break; 75 case 4: 76 if (stuck.base) 77 { 78 if (ifEmpty(stuck)) 79 cout << "栈不为空" << endl; 80 else 81 cout << "栈为空" << endl; 82 } 83 else 84 { 85 cout << "请初始化后再进行此操作" << endl; 86 } 87 system("pause"); break; 88 case 5: 89 if (stuck.base) 90 { 91 92 cout << "该栈的长度为: " <<(stuck.top - stuck.base) << endl; 93 } 94 else 95 { 96 cout << "请初始化后再进行此操作" << endl; 97 } 98 system("pause"); break; 99 case 6: 100 if (stuck.base) 101 { 102 if(ifEmpty(stuck)) 103 { 104 cout << " 栈顶元素为:" << getTop(stuck) << endl; 105 } 106 else 107 cout << "请插入元素后再进行此操作" << endl; 108 } 109 else 110 cout << "请初始化后再进行此操作" << endl; 111 system("pause"); break; 112 case 7: 113 if (stuck.base) 114 { 115 if((stuck.top-stuck.base)==stuck.stacksize) 116 { 117 cout << "栈已满,正在申请新的内存空间" << endl; 118 stuck.base = (element*)realloc(stuck.base,(STACKINCREMENT + STACK_INIT_SIZE) * sizeof(element)); 119 if (stuck.base) 120 { 121 stuck.top = stuck.stacksize + stuck.base; 122 stuck.stacksize += STACKINCREMENT; 123 } 124 else 125 { 126 cout << "申请失败,请联系管理员" << endl; 127 } 128 } 129 else { 130 element elem; 131 cout << "请输入要插入的元素" << endl; 132 cin >> elem; 133 insertElem(stuck,elem); 134 } 135 } 136 else 137 cout << "请初始化后再进行此操作" << endl; 138 system("pause"); break; 139 case 8: 140 if (stuck.base) 141 { 142 if (ifEmpty(stuck)) 143 deleteElem(stuck); 144 else { 145 cout<< "请添加元素后再进行删除操作" << endl; 146 } 147 } 148 else 149 { 150 cout << "请初始化后再进行此操作" << endl; 151 } 152 system("pause"); break; 153 case 9: 154 if (stuck.base) 155 { 156 if (ifEmpty(stuck)) 157 { 158 cout << "目前元素为:" << endl; 159 printElem(stuck); 160 } 161 else 162 cout << "栈为空" << endl; 163 } 164 else 165 cout << "请初始化后再进行此操作" << endl; 166 system("pause"); break; 167 case 10: 168 int num; 169 int num_system; 170 initializeStuck(trans_stuck); 171 cout << "请输入要转换的十进制数: " << endl; 172 cin >> num; 173 cout << "请输入要转换的数制" << endl; 174 cin >> num_system; 175 if(num == 0) //判断输入数为0的情况 176 cout<<num << "的" << num_system << "进制为:" <<0<< endl; 177 else if ((num_system > 10 && num_system != 16) || num_system < 2) 178 { 179 cout << "暂时不支持此进制的转换" << endl; 180 } 181 else 182 { 183 cout << num << "的" << num_system << "进制为:" << endl; 184 initializeStuck(trans_stuck); 185 while (num != 0) 186 { 187 int remainder = num % num_system; 188 insertElem(trans_stuck, remainder);//将余数压入栈中 189 num = num / num_system; 190 } 191 if (num_system == 16) //当转换进制为16时 192 { 193 while (trans_stuck.base != trans_stuck.top) 194 { 195 int choice = *(--trans_stuck.top); 196 switch (choice) 197 { 198 case 10:cout << "A"; break; 199 case 11:cout << "B"; break; 200 case 12:cout << "C"; break; 201 case 13:cout << "D"; break; 202 case 14:cout << "E"; break; 203 case 15:cout << "F"; break; 204 default:cout << choice; break; 205 } 206 } 207 } 208 else 209 printElem(trans_stuck); 210 } 211 destoryStuck(trans_stuck); //释放内存空间 212 system("pause"); break; 213 } 214 } 215 }
studck.h
1 #pragma once 2 #include <iostream> 3 using namespace std; 4 #define STACK_INIT_SIZE 100 5 #define STACKINCREMENT 10 6 typedef int element; 7 typedef struct 8 { 9 element *base; //栈底指针 10 element *top; //栈顶指针 11 int stacksize; // 当前已分配的存储空间 12 }Stuck; 13 void initializeStuck(Stuck &stuck); //初始化 14 void destoryStuck(Stuck& stuck); //销毁 15 void emptyStuck(Stuck& stuck); //清空 16 bool ifEmpty(Stuck stuck); //判断是否为空 17 element getTop(Stuck stuck); //获取栈顶元素 18 void insertElem(Stuck& stuck,element elem); //插入元素 19 void deleteElem(Stuck& stuck); //删除元素 20 void printElem(Stuck stuck); //输出所有元素
stuck.cpp
1 #include "stack.h" //引入头文件 2 //1 初始化栈 3 void initializeStuck(Stuck& stuck) 4 { 5 stuck.base = (element*)malloc(STACK_INIT_SIZE * sizeof(element)); 6 stuck.top = stuck.base; 7 stuck.stacksize = STACK_INIT_SIZE; 8 } 9 // 2 销毁栈 10 void destoryStuck(Stuck& stuck) 11 { 12 free(stuck.base); 13 stuck.stacksize = 0; 14 stuck.top = NULL; 15 stuck.base = NULL; 16 } 17 // 3 清空栈 18 void emptyStuck(Stuck& stuck) 19 { 20 stuck.top = stuck.base; 21 } 22 // 4 判断栈是否为空 23 bool ifEmpty(Stuck stuck) 24 { 25 if (stuck.top == stuck.base) 26 return false; 27 else 28 return true; 29 } 30 // 6 获取栈顶元素 31 element getTop(Stuck stuck) 32 { 33 /*int pos = (stuck.top - stuck.base) - 1; 34 return stuck.base[pos];*/ 35 return *(--stuck.top); 36 } 37 // 7 插入元素 38 void insertElem(Stuck& stuck, element elem) 39 { 40 //较麻烦,不推荐使用已注释的方法 41 /*int pos = stuck.top - stuck.base; 42 stuck.base[pos] = elem; 43 stuck.top++;*/ 44 *(stuck.top++) = elem; 45 } 46 // 8 删除元素 47 void deleteElem(Stuck& stuck) 48 { 49 stuck.top--; 50 } 51 // 9 输出所有元素 52 void printElem(Stuck stuck) 53 { 54 while (stuck.base != stuck.top) 55 { 56 cout << *(--stuck.top) << " "; 57 } 58 cout << endl; 59 //这种方法也可以使用,二者先选其一即可; 60 /*for (int i = 0; i < (stuck.top - stuck.base); i++) 61 { 62 cout << stuck.base[i] << " "; 63 } 64 cout << endl;*/ 65 }
实验结果总结
在未进行初始化前不可进行其它操作
初始化后栈为空,长度为0,不可获取栈顶元素也不能进行删除操作,输出元素则会提示栈为空;
插入两个数
求栈长
输出当前元素
删除一个元素并检查栈长,输出所有元素
获取栈顶元素
销毁栈
数制转换测试
输入负数退出程序(忘记在菜单中添加了,加上下面这条语句:cout << "输入负数退出程序" << endl;)
实验结果的运用:
1.熟悉了顺序栈的基本操作和运行原理;
2.对于16进制转换时,可以在输出时进行处理,因此并不妨碍进栈操作的进行;
3.在进行出栈操作时进行栈是否为空的判断,同时进栈时考虑分配的空间满的情况下,进行内存扩容。
进行实验时参考了以下内容:
https://blog.csdn.net/qq_24654501/article/details/109273418?ops_request_misc=&request_id=&biz_id=102&utm_term=%E7%94%A8%E9%A1%BA%E5%BA%8F%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84%EF%BC%8C%E5%AE%9E%E7%8E%B0%E6%95%99%E6%9D%90%E5%AE%9A%E4%B9%89%E7%9A%84%E6%A0%88%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C%EF%BC%8C%E6%8F%90%E4%BE%9B%E6%95%B0%E5%88%B6%E8%BD%AC%E6%8D%A2%E5%8A%9F%E8%83%BD&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-109273418.pc_search_result_hbase_insert&spm=1018.2226.3001.4187