(1)实验目的
通过该实验,让学生掌握栈的相关基本概念,认识栈是插入和删除集中在一端进行的线性结构,掌握栈的“先入后出”操作特点。栈在进行各类操作时,栈底指针固定不动,掌握栈空、栈满的判断条件。
(2)实验内容
用顺序存储结构,实现教材定义的栈的基本操作,提供数制转换功能,将输入的十进制整数转换成二进制、八进制或十六进制。
(3)参考界面
菜单中包括以下功能:
1.初始化栈,2.销毁栈,3.清空栈,4.栈判空,5.求栈长度,6.获取栈顶元素,7.插入一个 元素,8.删除一个元素,9输出所有元素,10进制转换。
要求:自定义的函数中不允许出现提示语和输出语句。
(4)验收/测试用例
通过菜单调用各个操作,测试点:
- 没有初始化前进行其他操作,程序是否能控制住;
- 初始化一个栈;
- 判栈空,屏幕显示栈为空;
- 3个数入栈, 2、4、6;
- 栈长度,屏幕输出3;
- 取栈顶元素,再判栈空,然后再判栈长度。让学生知道取栈顶元素不改变栈中的内容,栈顶指针不发生改变;
- 出栈,再判栈长度和输出栈中内容;(多次出栈,直到栈为空;再出栈,是否提示栈为空)
- 销毁栈,再做其他操作,判断程序是否能控制;
- 数制转换,(允许用户输入想把十进制转换成几进制),然后灵活的转换成对应的进制。
#include<iostream>
using namespace std;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
typedef int Status;
typedef int SElemType;
typedef struct {
SElemType* base;
SElemType* top;
int stacksize;
}SqStack;
//1.初始化栈
Status InitStack(SqStack& S) {
S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));//为顺序栈分配一个数组空间,使base指向这段空间的基地址
if (!S.base) exit(OVERFLOW);
S.top = S.base;//栈顶指针top初始为base,表示栈为空
S.stacksize = STACK_INIT_SIZE;//stacksize为最大容量
return OK;
}
//2.销毁栈
Status DestroyStack(SqStack& S) {
free(S.base);//释放栈中的空间
S.base = S.top = NULL;//让栈顶和栈尾同时为空
S.stacksize = 0;//栈的长度为0
return OK;
}
//3.清空栈
Status ClearStack(SqStack& S) {
S.top = S.base;//令栈顶等于栈尾
return OK;
}
//4.栈判空
Status StackEmpty(SqStack S) {
if (S.top ==S.base) {
return OK;//当栈顶等于栈尾时,返回正确
}
return ERROR;
}
//5.求栈长度
Status StackLength(SqStack S) {
return S.top - S.base;
}
//6.获取栈顶元素
Status GetTop(SqStack S, SElemType& e) {
if (S.top == S.base) {
return ERROR;
}
e = *(S.top - 1);//栈顶指向的是最后一个元素的下一个位置,所以需要在栈顶的基础上减一
return OK;
}
//7.插入一个元素
Status Push(SqStack& S, SElemType e) {
if (S.top - S.base >= S.stacksize)//当栈满时,需要重新申请空间
{
S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S.base) return OVERFLOW;
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top= e;//此时栈顶等于输入的数字
S.top++;//栈顶的位置向后移一位
return OK;
}
//8.删除一个元素
Status Pop(SqStack& S) {
SElemType e=0;
if (S.top == S.base) {
return ERROR;
}
else {
e = *(S.top - 1);
--S.top;//此时栈顶指向最后一个元素,元素内容省略
return e;
}
}
//9.输出所有元素
Status PrintElem(SqStack S) {
if (S.base != S.top) {
SElemType* p = S.top-1;//令p指向最后一个元素的位置
while (p>=S.base) {//当p大于等于栈底时,进入循环,实现栈的遍历
cout << *p <<" ";
p--;//p指向的位置向下移动
}
cout << endl;
}
else {
return ERROR;
}
}
//10.进制转换
Status BaseConversion(SqStack& S,SElemType e,int option) {
InitStack(S);
switch (option) {
case 1:
while (e != 0) {
int i = e % 2;
Push(S, i);
e = e/ 2;
}
break;
case 2:
while (e != 0) {
int i = e % 8;
Push(S, i);
e= e / 8;
}
break;
case 3:
while (e != 0) {
int i = e % 16;
if (i < 10) {
Push(S, i);
}
else {
if (i == 10) Push(S, 65);
if (i == 11) Push(S, 66);
if (i == 12) Push(S, 67);
if (i == 13) Push(S, 68);
if (i == 14) Push(S, 69);
if (i == 15) Push(S, 70);
}
e = e / 16;
}
break;
case 0:
break;
}
return OK;
}
int main() {
SqStack S;
S.base = NULL;
S.top = NULL;
cout << "1.初始化栈" << endl;
cout << "2.销毁栈" << endl;
cout << "3.清空栈" << endl;
cout << "4.栈判空" << endl;
cout << "5.求栈长度" << endl;
cout << "6.获取栈顶元素" << endl;
cout << "7.插入一个元素" << endl;
cout << "8.删除一个元素" << endl;
cout << "9输出所有元素" << endl;
cout << "10进制转换" << endl;
cout << "输入一个负数退出程序" << endl;
int flag = 1;
while (flag == 1) {
cout << "---------------------" << endl;
cout << "请输入你的选择:";
int op;
cin >> op;
switch (op) {
case 1:
InitStack(S);
if (S.base != NULL) {
cout << "顺序栈初始化成功" << endl;
}
else {
cout << "顺序栈初始化失败" << endl;
}
break;
case 2:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
DestroyStack(S);
if (S.base == NULL) {
cout << "栈销毁成功!" << endl;
}
else {
cout << "栈销毁失败!请重新销毁~" << endl;
}
}
break;
case 3:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else if (S.top == S.base) {
cout << "栈此时为空" << endl;
}
else {
ClearStack(S);
if (S.top == S.base) {
cout << "栈已清空" << endl;
}
else {
cout << "栈清空失败" << endl;
}
}
break;
case 4:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
if (StackEmpty(S)) {
cout << "栈此时为空" << endl;
}
else {
cout << "栈此时不为空" << endl;
}
}
break;
case 5:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
if (S.base == S.top) {
cout << "栈此时为空" << endl;
}
else {
cout << "栈的长度为" << StackLength(S) << endl;
}
}
break;
case 6:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
if (S.base == S.top) {
cout << "栈此时为空" << endl;
}
else {
SElemType e;
GetTop(S, e);
cout << "栈顶元素是" << e << endl;
}
}
break;
case 7:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
int select;
SElemType e;
do {
cout << "请输入要插入的元素:";
cin >> e;
Push(S, e);
cout << "元素" << e << "插入成功" << endl;
cout << "1.继续 2.退出 请选择:";
cin >> select;
} while (select == 1);
}
break;
case 8:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
if (S.base == S.top) {
cout << "栈此时为空" << endl;
}
else {
Pop(S);
cout << "栈顶元素已删除" << endl;
//cout << "栈顶元素是" << e << endl;
}
}
break;
case 9:
if (S.base == NULL) {
cout << "栈还未初始化!请先初始化" << endl;
}
else {
if (S.top == S.base) {
cout << "栈此时为空" << endl;
}
else {
PrintElem(S);
}
}
break;
case 10:
SElemType e;
int option;
cout << "1二进制" << endl;
cout << "2.八进制" << endl;
cout << "3.十六进制" << endl;
cout << "0.退出程序" << endl;
cout << "选择你要转换的进制:";
cin >> option;
//BaseConversion(S, e, option);
//PrintElem(S);
//cout << "长度为:"<<StackLength(S) << endl;
if (option == 1 || option == 2) {
cout << "请输入数字:";
cin >> e;
BaseConversion(S, e, option);
cout << "转化结果"<<endl;
cout << "长度为:" << StackLength(S) << endl;
/*
这是调用9打印函数打印
PrintElem(S);
*/
//这是直接移动top指针来打印
while (S.base != S.top) {
cout << *(--S.top);
}
}
//因为16进制涉及字母打印,单独列出
else if (option == 3) {
cout << "请输入数字:";
cin >> e;
BaseConversion(S, e, option);
cout << "转化结果"<<endl;
cout << "长度为:" << StackLength(S) << endl;
//这是直接移动top指针来打印
while (S.base != S.top) {
int num = Pop(S);
if (num <= 9) {
cout << num;
}
//A-F的显示
else{
switch (num) {
case 65:
cout << 'A' ;
break;
case 66:
cout << 'B' ;
break;
case 67:
cout << 'C';
break;
case 68:
cout << 'D';
break;
case 69:
cout << 'E';
break;
case 70:
cout << 'F';
break;
}
}
}
}
else if (option == 0) {
BaseConversion(S, e, option);
}
cout << endl;
DestroyStack(S);
cout << "栈已销毁" << endl;
break;
default:
if (op < 0) {
flag = 0;
cout << "退出程序!欢迎下次使用" << endl;
break;
}
else {
cout << "输入的指令有误." << endl;
}
}
}
}