实验4 顺序栈的基本操作 【简单易懂,代码直接运行,注释超级全】

实验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;
} 

下面手把手展示一下数据的输入问题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
赠人玫瑰,手留余香,👍也是这样嗷

在这里插入图片描述

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

henu-于笨笨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值