实验5、顺序栈的基本操作 注释超级全
(1)实验目的
通过该实验,让学生掌握栈的相关基本概念,认识栈是插入和删除集中在一端进行的线性结构,掌握栈的“先入后出”操作特点。栈在进行各类操作时,栈底指针固定不动,掌握栈空、栈满的判断条件。
(2)实验内容
用顺序存储结构,实现教材定义的栈的基本操作,提供数制转换功能,将输入的十进制整数转换成二进制。
(3)参考界面
(4)验收/测试用例
通过菜单调用各个操作,测试点:
没有初始化前进行其他操作,程序是否能控制住;
初始化一个栈;
判栈空,屏幕显示栈为空;
3个数入栈, 1、2、3;
栈长度,屏幕输出3;
取栈顶元素,再判栈空,然后再判栈长度。让学生知道取栈顶元素不改变栈中的内容,栈顶指针不发生改变;
出栈,再判栈长度;
销毁栈,再做其他操作,判断程序是否能控制;
数制转换,输入:8,输出:100
这个实验相对于实验三来说简单很多,总体代码量减少很多,都是数据结构的基本操作,最后涉及到看以一个进制之间的转换,代码在三天内完成的,注释超级清晰嗷,如果对你有帮助的话,点个👍吧
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
typedef int Status;
typedef int SElemType;
#define ok 1
#define error -2
#define false -1
#define overflow -2
#define maxsize 20
typedef struct{
SElemType *top;//定义头指针
SElemType *base;//定义尾指针
int stacksize;//栈可以用的最大容量
}SqStack;
//初始化栈函数
Status InitStack(SqStack &S)
{
S.base = (SElemType *)malloc(maxsize*sizeof(SElemType));
if(S.base == 0)
{
return overflow;
}
S.top = S.base;
S.stacksize = maxsize;//将栈的容量存为最大长度
return ok;
}
//销毁栈
Status DestoryStack(SqStack &S)
{
if(S.base == 0)
{
return error;
}
free(S.base);//释放尾结点
S.stacksize = 0;
S.base = NULL;//将尾指针指向空
S.top = S.base;
return ok;
}
//清空栈
Status ClearStack(SqStack &S)
{
if(S.base == 0)
{
return error;
}
S.top = S.base;
//S.stacksize = 0;
return ok;
}
//判断栈空
Status StackEmpty(SqStack &S)
{
if(S.base == 0)
{
return error;//栈未初始化
}
if(S.base == S.top)
{
return ok;//栈为空
}
else
{
return false;//栈不为空
}
}
//求栈长度
Status StackLength(SqStack &S)
{
if(S.base == 0)
{
return error;//栈未初始化
}
return S.top - S.base;
}
//获取栈顶元素
Status TopElem(SqStack &S,int *e)
{
if(S.base == 0)
{
return error;
}
if(S.base == S.top)
{
return false;//栈为空没有元素可以取到
}
SElemType *new1;
new1 = S.top - 1;//保持top指针不动,新建立一个指针让该指针指向top的前一个位置
*e = *new1;//返回此时的栈顶元素
return ok;
}
//插入一个元素
Status Push(SqStack &S,int e)
{
if(S.base == 0)
{
return error;
}
if(S.top - S.base == S.stacksize)
{
return false;//此时满栈满栈不能再插入元素
}
*S.top = e;//将e值压入栈顶位置
S.top++;//top指针上移
return ok;
}
//删除一个元素
Status Pop(SqStack &S)
{
if(S.base == 0)
{
return error;
}
if(S.base == S.top)
{
return false;//栈为空没有元素可以删除
}
S.top--;//top指针下移
return ok;
}
//输出所有元素
Status VisitStack(SqStack &S)
{
if(S.base == 0)
{
return error;
}
if(S.base == S.top)
{
return false;//栈为空没有元素可以输出
}
//int i;
int *q;
//q = S.base;
for(q = S.base;q < S.top;q++)
{
cout<<*q<<" ";
}
return ok;
}
//进制转换
Status jizhi(SqStack &S,int e,int j)
{
if(S.base == 0)
{
return error;//栈未初始化
}
while(e != 0)//e!=0,使得十进制数的每一个除的结果,都能对j取一次余数
{
//e = e / 8;
*S.top = e % j;//将每一次的余数存入栈中
e = e / j;//将e/j将商值保存到e中进行下次计算
S.top++;//top指针上移
}
while(S.base != S.top)//输出栈中元素,直到栈为空
{
S.top--;
if(*S.top < 10)
{
cout<<*S.top;//进制转化后的八进制数
}
else{
cout<<char(*S.top + 55);//当栈中的数值大于10时,让该数字加55达到A的asscii码,然后强制类型转换为char类型输出字母
}
//S.top--;
}
return ok;
}
int main()
{
int m,e,i,j,n;
SqStack S;
SqStack S1;
S.base = 0;
S1.base = 0;
cout<<"******************"<<endl;
cout<<"h e n u 于 笨 笨"<<endl;
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.初始化栈S1"<<endl;
cout<<"11.进制转换"<<endl;
cout<<"输入负数退出程序"<<endl;
cout<<"******************"<<endl;
do{
cout<<"请输入你的选择:"<<endl;
cin>>n;
switch(n)
{
case 1:
m = InitStack(S);
if(m == overflow)
{
cout<<"栈初始化失败!"<<endl;
}
if(m == ok)
{
cout<<"栈初始化成功!"<<endl;
}
break;
case 2:
m = DestoryStack(S);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == ok)
{
cout<<"栈销毁成功"<<endl;
}
break;
case 3:
m = ClearStack(S);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == ok)
{
cout<<"栈销毁成功"<<endl;
}
break;
case 4:
m = StackEmpty(S);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == false)
{
cout<<"栈不为空!"<<endl;
}
else if(m == ok)
{
cout<<"栈为空!"<<endl;
}
break;
case 5:
m = StackLength(S);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else
{
cout<<"栈的长度为:"<<m<<endl;
}
break;
case 6:
m = TopElem(S,&e);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == false)
{
cout<<"栈为空!"<<endl;
}
else if(m == ok)
{
cout<<"栈顶元素为:"<<e<<endl;
}
break;
case 7:
cout<<"请输入你要压栈的元素:"<<endl;
cin>>e;
m = Push(S,e);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == false)
{
cout<<"栈为满栈!"<<endl;
}
else if(m == ok)
{
cout<<"元素压栈成功!"<<endl;
}
break;
case 8:
m = Pop(S);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == false)
{
cout<<"栈为空栈!"<<endl;
}
else if(m == ok)
{
cout<<"元素出栈成功!"<<endl;
}
break;
case 9:
m = VisitStack(S);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == false)
{
cout<<"栈为空!"<<endl;
}
else if(m == ok)
{
cout<<"输出该栈的元素:"<<endl;
VisitStack(S);
cout<<endl;
}
break;
case 10:
m = InitStack(S1);
if(m == overflow)
{
cout<<"栈初始化失败!"<<endl;
}
if(m == ok)
{
cout<<"栈初始化成功!"<<endl;
}
break;
case 11:
cout<<"请输入一个十进制数:"<<endl;
cin>>e;
cout<<"请输入你要转化的进制数:"<<endl;
cin>>j;
m = jizhi(S1,e,j);
if(m == error)
{
cout<<"请先初始化栈!"<<endl;
}
else if(m == ok)
{
cout<<"十进制转化为"<<j<<"进制的数为:";
jizhi(S1,e,j);
cout<<endl;
}
break;
default:
cout<<"请输入1~12内的数!!"<<endl;
break;
}
}while(n > 0);
}
下面再来单独介绍一下进制之间的转换,这里是进制之间的随意转换,使用的算法是辗转相除法,注释超级清晰嗷
代码如下:
Status jizhi(SqStack &S,int e,int j)
{
if(S.base == 0)
{
return error;//栈未初始化
}
while(e != 0)//e!=0,使得十进制数的每一个除的结果,都能对j取一次余数
{
//e = e / 8;
*S.top = e % j;//将每一次的余数存入栈中
e = e / j;//将e/j将商值保存到e中进行下次计算
S.top++;//top指针上移
}
while(S.base != S.top)//输出栈中元素,直到栈为空
{
S.top--;
if(*S.top < 10)
{
cout<<*S.top;//进制转化后的八进制数
}
else{
cout<<char(*S.top + 55);//当栈中的数值大于10时,让该数字加55达到A的asscii码,然后强制类型转换为char类型输出字母
}
//S.top--;
}
return ok;
}
下面手把手展示一下数据的输入问题:
赠人玫瑰,手留余香,👍也是这样嗷