顺序栈—基本操作的实现及简单应用(C语言)(二)

简介: 顺序栈—基本操作的实现及简单应用(C语言)

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. 基本功能演示


①构造一个空栈

image.png

②批量元素入栈两次并判断长度以及打印(为了简便,每次入栈3个元素,分别为1,2,3)

image.png

image.png

image.png

image.png

image.png

③删除栈顶元素并返回其值

image.png

④插入新的栈顶元素520并打印顺序栈

image.png

image.png

⑤重置顺序栈并判断是否为空

image.png

image.png

⑥销毁顺序栈并判断是否为空

image.png

image.png

2. 简单应用演示


1.括号匹配

①输入一个不含括号的序列

image.png

image.png

②只输入一个括号

image.png

③输入左右括号数量相等但是并不匹配的序列

image.png

④输入一个符合要求的序列

image.png

2.数制转换

输入十进制下的数5转换为二进制下的数

image.png

总结


栈的本质是操作受限的线性表,,因此可称为限定性的数据结构。但从数据结构的角度看,它们是和线性表大不相同的一类重要的抽象数据类型。由于栈广泛的应用在各种软件系统中,因此在面向对象的程序设计中,是一种多型数据类型。

(附录)源码:


#include<stdio.h>#include<stdlib.h>#include<malloc.h>#include<windows.h>//函数结果状态代码 #define TRUE     1     //代码中出现TRUE相当于出现了1 #define FALSE    0     //出现FALSE相当于出现了0 #define OK       1     //出现OK相当于出现了1 #define ERROR    2     //出现ERROR相当于出现了2#define INFEASIBLE    -1#define OVERFLOW      -2 typedefintStatus;
typedefintSElemType; 
#define STACK_INIT_SIZE    100     //栈的储空间的初始分配量 #define STACKINCREMENT     10      //栈的存储空间的分配增量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;
}
相关文章
|
1天前
|
存储 算法 程序员
C语言:基础与应用的双重魅力
C语言:基础与应用的双重魅力
|
1天前
|
C语言
链栈的初始化以及用C语言表示进栈、出栈和判断栈空
链栈的初始化以及用C语言表示进栈、出栈和判断栈空
18 3
|
1天前
|
C语言
在C语言中数组作为函数参数的应用与示例
在C语言中数组作为函数参数的应用与示例
17 0
|
1天前
|
算法 C语言
在C语言中函数的递归调用及应用示例
在C语言中函数的递归调用及应用示例
16 1
|
1天前
|
C语言
在C语言中多维数组名作为函数参数的应用与示例
在C语言中多维数组名作为函数参数的应用与示例
15 0
|
1天前
|
机器学习/深度学习 算法 数据挖掘
【C 言专栏】C 语言与机器学习的应用
【5月更文挑战第6天】C语言在机器学习中扮演关键角色,以其高效性、灵活性和可移植性实现底层算法、嵌入式系统和高性能计算。在神经网络、决策树和聚类算法等领域的实现中不可或缺。C语言被用于TensorFlow和OpenCV等知名库的底层,常与C++、Python结合使用。尽管面临开发难度和适应新算法的挑战,但C语言在机器学习领域的价值和潜力将持续展现,为科技进步贡献力量。
【C 言专栏】C 语言与机器学习的应用
|
1天前
|
存储 缓存 算法
【C 言专栏】C 语言中的数据结构应用
【5月更文挑战第4天】本文探讨了C语言中的核心数据结构,包括数组、链表(单链表和双链表)、栈、队列、二叉树(如二叉搜索树和二叉堆)以及图结构。这些数据结构在程序设计中扮演着关键角色,如数组的快速访问、链表的动态管理、栈和队列的处理流程控制、树和图的复杂关系表示。理解并选择适当的数据结构可优化程序性能,而内存管理和算法优化则进一步提升效率。通过案例分析和展望未来发展趋势,本文旨在帮助读者深化对C语言数据结构的理解和应用。
【C 言专栏】C 语言中的数据结构应用
|
1天前
|
机器学习/深度学习 算法 C语言
【C言专栏】递归算法在 C 语言中的应用
【4月更文挑战第30天】本文介绍了递归算法在C语言中的应用,包括基本概念(通过调用自身解决子问题)、特点(调用自身、终止条件、栈空间)和实现步骤(定义递归函数、分解问题、设置终止条件、组合解)。文中通过阶乘计算和斐波那契数列两个案例展示了递归的使用,强调了递归可能导致的栈溢出问题及优化需求。学习递归有助于理解和应用“分而治之”策略。
|
1天前
|
存储 算法 程序员
【C言专栏】C 语言结构体的应用与实践
【4月更文挑战第30天】C语言中的结构体是自定义数据类型的关键,它组合不同类型的數據以创建新类型,尤其适合处理复杂对象如学生信息。通过定义结构体如`struct Student`,包含名字、学号和成绩,可以方便地实例化和访问成员。结构体在链表实现、函数参数传递和数组中都有广泛应用,如表示链表节点和处理批量数据。理解并熟练运用结构体对于C语言编程至关重要,能提升代码效率和可读性。
|
1天前
|
C语言
栈的问题:HDU—1022 Train Problem I(C语言)
栈的问题:HDU—1022 Train Problem I(C语言)

热门文章

最新文章