数据结构——栈(c)

本文详细介绍了栈(Stack)这一数据结构,包括栈的定义、顺序存储结构、共享栈、链式存储结构,以及栈在数制转换、括号匹配、迷宫求解、表达式求值和递归调用中的应用。通过C语言实现,阐述了栈的存储结构和操作方法。
摘要由CSDN通过智能技术生成

👍数据结构——栈(c)-受限线性表

本文使用C语言,采用顺序表的存储方式完成栈的表示和实现,以及栈的应用(包括数制转换、括号匹配、迷宫求解、表达式求值等)。


提示:以下是本篇文章正文内容

一、栈的定义

栈Stack 是限定在表尾进行插入或删除操作的线性表。

特点 后进先出

相关定义:
①栈顶top:表尾端
栈顶指针分两种:一种指向栈顶元素,一种指向栈顶元素的下一位。
下文所述内容栈顶指针均指向栈顶元素。
②栈底bottom:表头端
③空栈:不含元素的空表
④入栈push:
⑤出栈pop:

二、栈的顺序存储结构

顺序栈的定义:

//----- 栈的顺序存储表示 ------//
#define STACK_INIT_SIZE 100    /*存储空间初始分配量*/
#define STACKINCREMENT 10     /*存储空间分配增量*/
typedef struct{
   
    int *base;     //栈底指针
    int *top;     //栈顶指针
    int stacksize;     //当前已分配的存储空间,以元素为单位
}SqStack;

基本操作

//----- 基本操作的函数原型说明 ------//
void InitStack(SqStack *S); //初始化栈
void DestoryStack(SqStack *S); //销毁栈
void ClearStack(SqStack *S); //清空栈
bool StackEmpty(SqStack *S); //判断栈是否为空
int StackLength(SqStack *S); //返回栈的长度
int GetTop(SqStack *S); //获取栈顶元素
void Push(SqStack *S, int e); //入栈
void Pop(SqStack *S, int *e); //出栈

具体实现
1.初始化栈S

void InitStack(SqStack *S){
   
    S->base = (int *)malloc(STACK_INIT_SIZE * sizeof(int));
    if(!S->base)
        printf("内存分配失败!");
    S->top = S->base;
    S->stacksize = STACK_INIT_SIZE;
}

2.销毁栈S

void DestoryStack(SqStack *S){
   
    free(S->base);
    S->base = NULL;
    S->top = NULL;
    S->stacksize = 0;
}

3.将栈S清为空栈

void ClearStack(SqStack *S){
   
    S->top = S->base;
}

4.判断栈S是否为空

bool StackEmpty(SqStack *S){
   
    if(S->base==S->top) return true;
    else return false;
}

5.获取栈S的长度

int StackLength(SqStack *S){
   
    int n;
    n = S->top - S->base;
    return n;
}

6.获取栈顶元素,但不从栈中移走

int GetTop(SqStack *S){
   
    int e;
    if(S->top == S->base)
        return -1;
    e = *(S->top - 1);
    return e;
}

7.将元素e放入栈顶

void Push(SqStack *S, int e){
   
    if(S->top - S->base >= S->stacksize){
   
        S->base = (int *)realloc(S->base, (S->stacksize+STACKINCREMENT)*sizeof(int));
        if(!S->base) printf("内存分配失败!");
        S->top = S->base + S->stacksize;
        S->stacksize += STACKINCREMENT;
    }
    *S->top++ = e;
}

8.移走栈顶元素,同时由e带来该元素的值

void Pop(SqStack *S, int *e){
   
    if(S->top == S->base)
        printf("栈内没有元素!");
    --S->top;
    *e = *S->top;
}

三、共享栈

利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。
共享栈是为了更有效地利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才发生上溢。
其存储数据的时间复杂度均为O(1),所以对存储效率没有影响。

四、栈的链式存储结构

采用链式存储的栈称为链栈
优点:便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。便于节点的插入和删除。
注:通常采用单链表实现,并规定所有操作都是在单链表的表头进行的。
分为:带头结点的链栈不带头结点的链栈(更推荐)

五、栈的应用

1.数制转换

问题描述:十进制数N和其他d进制数的转换是计算机实现计算的基本问题,其解决方法有很多,其中一个简单算法基于下列原理:

N = (N div d)× d + N mod d

现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数,打印与其等值的八进制数。

代码如下:
//栈的基本操作如上所述不变

void conversion(){
   
    SqStack S;
    int n, e;
    InitStack(&S);
    printf("请输入一个非负十进制数:\n");
    scanf("%d", &n);
    while(n){
   
        Push(&S,n%8);
        n = n/8;
    }
    while(!StackEmpty(&S)){
   
        Pop(&S, &e);
        printf("%d", e);
    }
}

在这里插入图片描述


2.括号匹配的检验

问题描述:一个算术表达式含圆括号、中括号、花括号,且它们可任意嵌套使用。
写一程序,判断任一算术表达式中所含括号是否正确配对。

检验括号是否匹配的方法可用“期待的急迫程度”这个概念来描述。
左括号直接放进去,右括号与栈顶元素进行比较。

代码如下:
//需要对栈的基本操作做出相应的修改,具体不详述。

char GetTop(SqStack *S); //获取栈顶元素
void Push(SqStack *S, char e); //入栈
void Pop(SqStack *S, char *e); //出栈
bool BracketMatch(char c[]){
   
    SqStack S;
    InitStack(&S);
    bool flag = 1;
    char demo
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值