2. 数制转换
代码如下:
//数制转换voidconversion(intNum,inttime) { inte,Elem; Elem=Num; SqStackS; S.base=S.top=NULL; //将空栈的栈顶和栈底指针赋值为NULL,因为此时并未对栈进行任何操作InitStack(S); //构造一个空栈while(Num) { Push(S,Num%time); Num=Num/time; } printf("10进制整数%d对应的%d进制整数的值为:",Elem,time); while(!StackEmpty(S)) //如果此时栈为空栈 { e=Pop(S); //使用e接收删除的栈顶的值 printf("%d",e); } printf("\n"); //换行 }
思路:
十进制N和其它进制数的转换是计算机实现计算的基本问题,基于下列原理:
N=(n div d)*d+n mod d
( 其中:div为整除运算,mod为求余运算)
因此,如果将计算过程中所得到的其他进制的数的各位顺序进栈,则按出栈序列打印输出的即为与输入对应的其他进制数。
代码解释:
Num为要转换的十进制下的数,time为对应的其他进制的数
构造一个空栈用于存储所得的余数,利用while循环不断的将Num与time的余数入栈,再将Num的值变为Num/time,当Num为0退出while循环时再利用一次while来将之前入栈的元素依次出栈,所得即为十进制转换为对应进制下的数。
四. 运行结果演示:
1. 基本功能演示
①构造一个空栈
②批量元素入栈两次并判断长度以及打印(为了简便,每次入栈3个元素,分别为1,2,3)
③删除栈顶元素并返回其值
④插入新的栈顶元素520并打印顺序栈
⑤重置顺序栈并判断是否为空
⑥销毁顺序栈并判断是否为空
2. 简单应用演示
1.括号匹配
①输入一个不含括号的序列
②只输入一个括号
③输入左右括号数量相等但是并不匹配的序列
④输入一个符合要求的序列
2.数制转换
输入十进制下的数5转换为二进制下的数
总结
栈的本质是操作受限的线性表,,因此可称为限定性的数据结构。但从数据结构的角度看,它们是和线性表大不相同的一类重要的抽象数据类型。由于栈广泛的应用在各种软件系统中,因此在面向对象的程序设计中,是一种多型数据类型。
(附录)源码:
//函数结果状态代码 //代码中出现TRUE相当于出现了1 //出现FALSE相当于出现了0 //出现OK相当于出现了1 //出现ERROR相当于出现了2typedefintStatus; typedefintSElemType; //栈的储空间的初始分配量 //栈的存储空间的分配增量typedefstruct{ SElemType*top; //栈顶指针 SElemType*base; //栈底指针,在构造栈时和销毁栈时均为NULL intstacksize; //当前已经分配的存储空间 }SqStack; //构造一个空的顺序栈 StatusInitStack(SqStack&S) { S.base= (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType)); //开辟一块连续的空间 if(!S.base) //如果存储空间分配失败 exit(OVERFLOW); S.top=S.base; //当栈为空栈时栈底和栈顶指针位置相同S.stacksize=STACK_INIT_SIZE; //更新栈的空间大小returnOK; } //批量元素入栈StatusValueStack(SqStack&S,intNum) { if(!S.base){ //如果栈不存在 printf("栈不存在,元素无法入栈\n"); returnERROR; } if(S.base!=S.top){ //判断传来的顺序栈中是否为空栈if(Num>=S.stacksize){ //如果要入栈的元素数量大于栈的空间大小 S.base= (SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT) *sizeof(SElemType)); S.stacksize=S.stacksize+STACKINCREMENT; //更新栈的空间大小 } inttemp[Num]; //定义一个辅助数组 for(inti=1;i<=Num;i++){ printf("请输入第%d个元素的值:",i); scanf("%d",&temp[i-1]); //将之后输入的值暂时存储在临时数组中 } for(intj=1;j<=Num;j++){ *S.top=temp[j-1]; S.top++; } printf("%d个元素入栈成功\n",Num); } else{ for(inti=1;i<=Num;i++){ printf("请输入第%d个元素的值:",i); scanf("%d",&S.base[i-1]); *(S.top++); } printf("%d个元素入栈成功\n",Num); } //这条语句的目的是为了检测栈顶指针的位置是否在栈顶元素的下一个位置//如果输出的值等于输入元素的个数,则说明此时栈顶指针和栈底指针的位置都在正确的位置 // printf("%d\n",S.top-S.base); returnOK; } //对顺序栈进行销毁 StatusDistoryStack(SqStack&S) { if(!S.base){ printf("顺序栈不存在,无法销毁\n"); returnERROR; } free(S.base); //使用free函数,将之前动态分配的内存还给系统 S.stacksize=0; //将栈的存储容量重置为0S.top=NULL; //重置栈顶指针为NULL S.base=NULL; //重置栈底指针为NULLprintf("顺序栈销毁成功\n"); returnOK; } //对顺序栈进行重置 StatusClearStack(SqStack&S) { if(!S.base){ printf("顺序栈不存在,不需要进行重置\n"); returnERROR; } S.top=S.base; //将栈底指针赋值给栈顶指针 /*重置顺序栈时只需要将栈底指针的地址赋值给栈顶指针就可以了因为栈顶指针和栈底指针都没有指向之前赋值过的元素,而且S.top=S.base时认为栈为空栈其次在开辟一块连续的存储地址时,地址内也会有原本的值,开辟出的新空间并不是空的在之后无论是销毁栈又或者是重新给栈进行赋值时都会将之前赋的值覆盖掉 */printf("顺序栈重置成功\n"); returnOK; } //判断顺序栈是否为空StatusStackEmpty(SqStackS) { if(!S.base) returnERROR; if(S.top==S.base) returnTRUE; elsereturnFALSE; } //获取顺序栈的长度StatusStackLength(SqStackS) { if(!S.base){ printf("顺序栈不存在,没有长度\n"); returnERROR; } intK; K=S.top-S.base; /*为什么顺序表中有length而顺序栈中却没有length因为在顺序栈中,栈的长度就是S.top-S.base*/printf("栈的长度为:%d\n",K); returnOK; //返回顺序栈的长度 } //获取栈顶元素StatusGetTop(SqStackS) { if(!S.base){ printf("顺序栈不存在,不存在栈顶元素\n"); returnERROR; }elseif(S.base==S.top){ printf("顺序栈为空栈,不存在栈顶元素\n"); returnERROR; } inte; e=*(S.top-1); printf("栈顶元素为:%d\n",e); returnOK; } //插入新的栈顶元素并返回其值 StatusPush(SqStack&S,SElemTypee) { if(!S.base){ printf("顺序栈不存在,无法插入新的栈顶元素\n"); returnERROR; } elseif(S.top-S.base>=S.stacksize) //此时顺序栈已满,追加存储空间 { if(!S.base){ //如果存储空间分配失败 printf("存储空间分配失败\n"); exit(OVERFLOW); } S.base= (SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT) *sizeof(SElemType)); S.top=S.base+S.stacksize; S.stacksize=S.stacksize+STACKINCREMENT; //更新栈的空间大小 } *S.top=e; S.top++; returne; //返回新插入的栈顶元素的值 } //打印顺序栈StatusPrintStack(SqStackS) { if(!S.base){ printf("顺序栈不存在,无法打印\n"); returnERROR; } elseif(S.base==S.top) printf("顺序栈为空栈\n"); printf("当前顺序栈的元素为:"); for(inti=0;i< (S.top-S.base);i++){ printf(" %d",S.base[i]); } printf("\n"); //换行 returnOK; } //删除栈顶元素并返回其值StatusPop(SqStack&S) { if(!S.base) return-1; elseif(S.base==S.top) return-2; SElemTypee; e=*(S.top-1); S.top=S.top-1; returne; //返回被删除的栈顶元素的值 } /*遇到的问题会有以下几点1. 当输入的一个序列中没有括号时2. 当只输入一个右括号时 3. 左右两边的括号数目相同但是却不是配对的括号 *///括号匹配的检验Statusexamine(char*List) { SqStackS; S.base=S.top=NULL; //将空栈的栈顶和栈底指针赋值为NULL,因为此时并未对栈进行任何操作InitStack(S); //构造一个空栈intresult; inttemp=0; intfinal=0; intlength=strlen(List); //获取字符数组的长度 charArrays[length]; //定义一个与传来的字符数组长度相等的字符数组作为辅助数组 if(length==1) { printf("输入的序列括号不匹配\n"); printf("输入的序列长度为:%d\n",length); returnERROR; } for(inti=0;i<length;i++) { switch(List[i]) //利用switch语句来控制括号的入栈和出栈 { case'(': case'[': case'{': { Arrays[i] =Push(S,List[i]); temp=1; }break; case')': case']': case'}': { Arrays[i] =Pop(S); if(Arrays[i] =='('&&List[i] !=')') //如果遇到了右括号判断是否与之前入栈的左括号对应 final=-1; //如果左括号与右括号不匹配就将final的值修改为-1 elseif(Arrays[i] =='['&&List[i] !=']') final=-1; elseif(Arrays[i] =='{'&&List[i] !='}') final=-1; } } } if(StackEmpty(S) &&temp!=1){ printf("您输入的序列中没有括号\n"); final=2; } if(temp==1&&!StackEmpty(S)){ printf("输入的序列括号不匹配\n"); printf("输入的序列长度为:%d\n",length); returnOK; } if(final==-1) { printf("输入的序列括号不匹配\n"); printf("输入的序列长度为:%d\n",length); returnOK; }elseif(final==0&&temp==1) { result=StackEmpty(S); //使用result接收判断是否为空栈的结果if(result==TRUE) printf("输入的序列括号匹配\n"); elseif(result==FALSE) printf("输入的序列括号不匹配\n"); printf("输入的序列长度为:%d\n",length); // printf("%s\n",Arrays); //这条语句用于检测出栈的顺序 } returnOK; } //数制转换voidconversion(intNum,inttime) { inte,Elem; Elem=Num; SqStackS; S.base=S.top=NULL; //将空栈的栈顶和栈底指针赋值为NULL,因为此时并未对栈进行任何操作InitStack(S); //构造一个空栈while(Num) { Push(S,Num%time); Num=Num/time; } printf("10进制整数%d对应的%d进制整数的值为:",Elem,time); while(!StackEmpty(S)) //如果此时栈为空栈 { e=Pop(S); //使用e接收删除的栈顶的值 printf("%d",e); } printf("\n"); //换行 } intmain() { SetConsoleTitle("Dream_飞翔"); //控制windows终端控制台的名称 SqStackS; S.base=S.top=NULL; //将栈顶和栈底指针赋值为NULL,因为此时并未对栈进行任何操作intchoose,index,Num,e,time,final; while(1){ printf("*****************************************\n"); printf("* *\n"); printf("* 顺序栈的顺序表示和实现: *\n"); printf("* *\n"); printf("* 1. 构造一个空的顺序栈 *\n"); printf("* 2. 批量元素入栈 *\n"); printf("* 3. 对顺序栈进行销毁 *\n"); printf("* 4. 对顺序栈进行重置 *\n"); printf("* 5. 判断顺序栈是否为空 *\n"); printf("* 6. 获取顺序栈的长度 *\n"); printf("* 7. 获取栈顶元素 *\n"); printf("* 8. 插入新的栈顶元素并返回其值 *\n"); printf("* 9. 删除当前栈顶元素并返回其值 *\n"); printf("* 10. 打印顺序栈 *\n"); printf("* *\n"); printf("*****************************************\n"); printf("* *\n"); printf("* 栈的简单应用: *\n"); printf("* *\n"); printf("* 11. 括号匹配的检验 *\n"); printf("* 12. 数制转换 *\n"); printf("* *\n"); printf("*****************************************\n"); printf("* 13. 退出 *\n"); printf("*****************************************\n"); printf("请做出您的选择:"); scanf("%d",&choose); switch(choose){ case1:{ final=InitStack(S); if(final==OK) printf("空栈构造成功\n"); } break; case2: { printf("请压入顺序栈的元素个数:"); scanf("%d",&Num); ValueStack(S,Num); } break; case3:DistoryStack(S);break; case4:ClearStack(S);break; case5:{ final=StackEmpty(S); if(final==ERROR){ printf("顺序栈不存在,无法判断是否为空\n"); break; } elseif(final==TRUE) printf("顺序栈是空栈\n"); elseprintf("顺序栈不是空栈\n"); } break; case6:StackLength(S);break; case7:GetTop(S);break; case8:{ printf("请输入要压入的元素:"); scanf("%d",&e); final=Push(S,e); if(final==e) printf("新的栈顶元素插入成功\n"); } break; case9:{ final=Pop(S); if(final==-1){ printf("顺序栈不存在,无法删除栈顶元素\n"); break; }elseif(final==-2){ printf("顺序栈为空栈,无法删除栈顶元素\n"); break; } printf("栈顶元素删除成功\n"); printf("删除的栈顶元素为:%d\n",final); } break; case10:PrintStack(S);break; case11: { charList[30]; printf("请输入一个带有括号的序列:"); scanf("%s",List); examine(List); } break; case12:{ printf("请输入一个非负的十进制整数:"); scanf("%d",&Num); printf("请输入想要将其转换成多少进制下的数:"); scanf("%d",&time); if(time<=0) { printf("请输入一个有效值\n"); break; } conversion(Num,time); } break; case13:exit(0); } } return0; }