C语言数据结构 | 堆栈顺序、链式存储及表达式求值

简介: 从计算机对表达式求值引入算数表达式在求值时若无优先级,那么从左到右运算就很容易,但算术表达式由两类对象构成一个是一个是+-*/······不同的运算符号优先级也不一样此时运算就比较困难 ,无法判断运算符后一个运算数是否参与这次运算。

目录

前言

表达式

堆栈 (Stack)

栈的顺序存储

栈的链式存储

CreateStack操作

Push操作

pop操作

堆栈应用:表达式求值

步骤

堆栈的其他应用


前言

从计算机对表达式求值引入

算数表达式在求值时若无优先级,那么从左到右运算就很容易,但算术表达式由两类对象构成

一个是运算数:1、2、3、······

一个是运算符号:+-*/······

不同的运算符号优先级也不一样

此时运算就比较困难 ,无法判断运算符后一个运算数是否参与这次运算

image.gif编辑

表达式

中缀表达式:运算符号位于两个运算符之间。如a+b*c-d/e

后缀表达式:运算符号位于两个运算数之后。如abc*+de/-

后缀表达式求值,以下面的式子为例

8 4 / 2 - 4 2 * + = ?

在运算中只需从左往右计算即可

首先出现8 而后4 后面出现 /,即表示8/4=2;紧接着出现了2和-,那么目前出现的数值就是2 2 -=0;此时042*=08,然后最后的+代表0和8相加0+8=8

堆栈:先放进去的后拿出来,后放进去的后拿出来(后入先出 Last In First Out (LIFO))image.gif编辑

堆栈 (Stack)

具有一定操作约束的线性表

只在一端(栈顶,Top)做插入、删除

插入数据:入栈(Push)

删除数据:出栈(Pop)

类型名称:堆栈(Stack)

数据对象集:一个有0个或多个元素的有穷线性表

操作集:长度为MaxSize的堆栈S∈Stack,堆栈元素item ∈ ElementType

Stack CreateStack(int MaxSize)    //生成空堆栈,最大长度为MaxSize
int IsFull(Stack S,int MaxSize)        //判断堆栈S是否已满
void Push(Stack S,ElementType item)    //将元素item压入堆栈
int IsEmpty(Stack S)              //判断堆栈S是否为空
ElementType Pop(Stack S)          //删除并返回栈顶元素

image.gif

栈的顺序存储

栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成。

#defube NaxSuze //存储数据元素的最大个数
typedef struct SNode *Stack;
struct SNode{
        ElementType Data[MaxSize];
        int Top;
};

image.gif

栈的链式存储

栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行

typedef struct SNode *Stack;
struct SNode{
        ElementType Data;
        struct SNode *Next;
};

image.gif

CreateStack操作

Stack CreateStack()
{        /*构建一个堆栈的头节点,返回指针*/
    Stack S;
    S = (Stack)malloc(sizeof(struct SNode));
    S->Next = NULL;
    return S;
}
int IsEmpty(Stack S)
{                /*判断堆栈s是否为空,若为空返回1,否则返回0*/
    return(S->Next == NULL);
}

image.gif

Push操作

void Push(ElementType item, Stack S)
{        /*将元素item压入堆栈s*/
    struct SNode *TmpCell;
    TmpCell=(struct SNode *)malloc(sizeof(struct SNode));
    TmpCell->Element = item;
    TmpCell->Next = S->Next;
    S->Next = TmpCell;
}

image.gif

pop操作

ElementType Pop(stack S)
{        /*删除并返回堆栈S的栈顶元素*/
    struct SNode *FirstCell;
    ElementType TopElem;
    if(IsEmpty(S)){
        printf("堆栈空");
        return NULL;
}else{
    FirstCell = S->Next;
    S->Next = FirstCell->Next;
    TopElem = FirstCell ->Element;
    free(FirstCell);
    return TopElem;
}

image.gif

堆栈应用:表达式求值

中缀表达式求值

基本策略:将中缀表达式转换为后缀表达式求值

转换后的特点:

    1. 运算数相对顺序不变
    2. 运算符号顺序发生改变
      1. 需要存储“等待中”的运算符号
      2. 要将当前运算符号与“等待中”的最后一个运算符号比较

        image.gif编辑

        步骤

        从头到尾读取中缀表达式的每个对象,对不同对象按不同情况处理。

          • 运算数:直接输出
          • 左括号:压入堆栈
          • 右括号将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出);
          • 运算符
            • 优先级大于栈顶运算符时,则把它压栈;
            • 优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出;再比较新的栈顶运算符,直到该运算符大于栈顶运算符优先级为止,然后将该运算符压栈
              • 若各对象处理完毕,则把堆栈中存留的运算符一并输出

              堆栈的其他应用

              函数调用及递归实现

              深度优先搜索

              回溯算法······

              相关文章
              |
              9天前
              |
              C语言
              【数据结构】栈和队列(c语言实现)(附源码)
              本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
              75 9
              |
              8天前
              |
              存储 搜索推荐 算法
              【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
              本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
              48 16
              |
              2月前
              |
              存储 编译器 C语言
              C语言存储类详解
              在 C 语言中,存储类定义了变量的生命周期、作用域和可见性。主要包括:`auto`(默认存储类,块级作用域),`register`(建议存储在寄存器中,作用域同 `auto`,不可取地址),`static`(生命周期贯穿整个程序,局部静态变量在函数间保持值,全局静态变量限于本文件),`extern`(声明变量在其他文件中定义,允许跨文件访问)。此外,`typedef` 用于定义新数据类型名称,提升代码可读性。 示例代码展示了不同存储类变量的使用方式,通过两次调用 `function()` 函数,观察静态变量 `b` 的变化。合理选择存储类可以优化程序性能和内存使用。
              153 82
              |
              8天前
              |
              C语言
              【数据结构】二叉树(c语言)(附源码)
              本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
              41 8
              |
              10天前
              |
              存储 C语言
              【数据结构】手把手教你单链表(c语言)(附源码)
              本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
              37 4
              |
              12天前
              |
              存储 C语言
              【数据结构】顺序表(c语言实现)(附源码)
              本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
              38 3
              |
              25天前
              |
              存储 安全 数据库
              除了 HashMap,还有哪些数据结构可以实现键值对存储?
              【10月更文挑战第11天】 除了`HashMap`,其他常见支持键值对存储的数据结构包括:`TreeMap`(基于红黑树,键有序)、`LinkedHashMap`(保留插入顺序)、`HashTable`(线程安全)、`B-Tree`和`B+Tree`(高效存储大量数据)、`SkipList`(通过跳跃指针提高查找效率)及`UnorderedMap`(类似`HashMap`)。选择合适的数据结构需根据排序、并发、存储和查找性能等需求。
              |
              2月前
              |
              存储 Java
              java数据结构,线性表链式存储(单链表)的实现
              文章讲解了单链表的基本概念和Java实现,包括头指针、尾节点和节点结构。提供了实现代码,包括数据结构、接口定义和具体实现类。通过测试代码演示了单链表的基本操作,如添加、删除、更新和查找元素,并总结了操作的时间复杂度。
              java数据结构,线性表链式存储(单链表)的实现
              |
              1月前
              |
              C语言
              链式顺序表实现(C语言描述)
              本文介绍了如何在C语言中实现链式顺序表,包括数据结构的定义、节点的创建、数据的插入和删除以及链表的打印和销毁。
              35 2
              |
              10天前
              |
              C语言
              【数据结构】双向带头循环链表(c语言)(附源码)
              本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
              28 0