利用栈的顺序存储结构,设计一组输入数据(假定为一组整数),能够对顺序栈进行如下操作:
初始化一个空栈,分配一段连续的存储空间,且设定好栈顶和栈底;
完成一个元素的入栈操作,修改栈顶指针;
完成一个元素的出栈操作,修改栈顶指针;
读取栈顶指针所指向的元素的值;
l 将十进制数N和其它d进制数的转换是计算机实现计算的基本问题,其解决方案很多,其中最简单方法基于下列原理:
即除d取余法。例如:(1348)10=(2504)8
NNdiv8
Nmod8
1348168416821021252
0
2
从中我们可以看出,最先产生的余数4是转换结果的最低位,这正好符合栈的特性即后进先出的特性。所以可以用顺序栈来模拟这个过程。以此来实现十进制数与八进制数的转换,十进制数与十六进制数的转换;编写主程序,实现对各不同的算法调用
(1) 首先将顺序栈存储结构定义放在一个头文件:如取名为SqStackDef.h。
(2) 将顺序栈的基本操作算法也集中放在一个文件之中,如取名为SqStackAlgo.h。如:InitStack、
(3) DestroyStack、ClearStack、StackEmpty、StackLength、GetTop、Push、Pop、conversion10_8、conversion10_16等。
(4) 将函数的测试和主函数组合成一个文件,如取名为SqStackUse.cpp。
pubuse.h
#include<string.h>
#include<ctype.h>
#include<malloc.h>/*malloc()等*/
#include<limits.h>/*INT_MAX等*/
#include<stdio.h>/*EOF(=^Z或F6),NULL*/
#include<stdlib.h>/*atoi()*/
#include<io.h>/*eof()*/
#include<math.h>/*floor(),ceil(),abs()*/
#include<process.h>/*exit()*/
/*函数结果状态代码*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/*#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/
typedef int Status;/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
typedef int Boolean;/*Boolean是布尔类型,其值是TRUE或FALSE*/
SqStackDef.h中实现了栈的顺序存储表示
#define STACK_INIT_SIZE 10/*存储空间初始分配量*/
#define STACKINCREMENT 2/*存储空间分配增量*/
typedef struct SqStack{
SElemType *base;/*在栈构造之前和销毁之后,base的值为NULL*/
SElemType *top;/*栈顶指针*/
int stacksize;/*当前已分配的存储空间,以元素为单位*/
}SqStack;/*顺序栈*/
对顺序栈的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价。
“初始化栈算法”操作结果:构造一个空栈S;
“销毁栈算法”操作结果:销毁栈S,S不再存在;
“置空栈算法”操作结果:把S置为空栈;
“判是否空栈算法”操作结果:若栈S为空栈,则返回TRUE,否则返回FALSE;.“求栈的长度算法”操作结果:返回S的元素个数,即栈的长度;
“取栈顶元素算法”操作结果:若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR;
“入栈算法”操作结果:插入元素e为新的栈顶元素
“出栈算法”操作结果:若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR.“实现十进制数与八进制数的转换算法”操作结果:输入任意一个非负的十进制数,输出对应的八进制数;
“实现十进制数与十六进制数的转换算法”操作结果:输入任意一个非负的十进制数,输出对应的十六进制数;
SqStackAlgo.h中实现顺序栈的基本操作
Status InitStack(SqStack &S)
{/*构造一个空栈S*/
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);/*存储分配失败*/
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status DestroyStack(SqStack &S)
{/*销毁栈S,S不再存在*/
free(S.base);S.base=NULL;S.top=NULL;S.stacksize=0;
return OK;
}
Status ClearStack(SqStack &S)
{/*把S置为空栈*/
S.top=S.base;
return OK;
}
Status StackEmpty(SqStack S)
{/*若栈S为空栈,则返回TRUE,否则返回FALSE*/
if(S.top==S.base)return TRUE;
else return FALSE;
}
int StackLength(SqStack S)
{/*返回S的元素个数,即栈的长度*/
return S.top-S.base;
}
Status GetTop(SqStack S,SElemType &e)
{/*若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR*/
if(S.top>S.base){
e=*(S.top-1);
return OK;
}
else return ERROR;
}
Status Push(SqStack &S,SElemType e){/*插入元素e为新的栈顶元素*/
if(S.top-S.base>=S.stacksize)/*栈满,追加存储空间*/
{ S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base)exit(OVERFLOW);/*存储分配失败*/
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*(S.top)++=e;
return OK;
}
Status Pop(SqStack &S,SElemType &e)
{/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/
if(S.top==S.base)return ERROR;
e=*--S.top;
return OK;
}
Status StackTraverse(SqStack S,Status(*visit)(SElemType))
{/*从栈底到栈顶依次对栈中每个元素调用函数visit()。*//*一旦visit()失败,则操作失败*/
while(S.top>S.base)visit(*S.base++);
printf("\n");
return OK;
}
void conversion10_8()
/*算法3.1*/
{/*对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数*/
SqStack s;unsigned n;/*非负整数*/
SElemType e;
InitStack(s);/*初始化栈*/
printf("Enter a nnumber(>=0):");
scanf("%u",&n);
/*输入非负十进制整数n*/while(n)/*当n不等于0*/
{
Push(s,n%8);/*入栈n除以8的余数(8进制的低位)*/n=n/8;
}
while(!StackEmpty(s))/*当栈不空*/
{
Pop(s,e);/*弹出栈顶元素且赋值给e*/
printf("%d",e);/*输出e*/
}
printf("\n");
}
void conversion10_16()
{/*对于输入的任意一个非负10进制整数,打印输出与其等值的16进制数*/
SqStack s;
unsigned n;/*非负整数*/
SElemType e;
InitStack(s);/*初始化栈*/
printf("Enter a nnumber(>=0):");
scanf("%u",&n);/*输入非负十进制整数n*/
while(n)/*当n不等于0*/
{
Push(s,n%16);/*入栈n除以16的余数(16进制的低位)*/
n=n/16;
}
while(!StackEmpty(s))/*当栈不空*/
{
Pop(s,e);/*弹出栈顶元素且赋值给e*/
if(e<=9)
printf("%d",e);
else
printf("%c",e+55);
}
printf("\n");
}
SqStackUse.cpp文件中,测试算法3.1的调用,其中间接调用了顺序栈的其他基本算法
typedef int SElemType;/*定义栈元素类型为整型*/
#include"pubuse.h"
/*常量定义与系统函数原型声明,与实验一中的相同*/
#include"SqStackDef.h"/*采用顺序栈的类型定义*/
#include"SqStackAlgo.h"
/*利用顺序栈的基本操作*/
int main()
{
conversion10_8();/*十进制数到八进制转换的验证*/
conversion10_16();/*十进制数到十六进制转换的验证*/
return 0;
}