C语言数据结构之栈简单操作

yizhihongxing

C语言数据结构之栈简单操作

什么是栈?

栈(Stack)是一种线性数据结构,它具有“后进先出”(Last-In-First-Out)的特性。栈顶是栈的一端,另一端称为栈底。每次只能从栈顶插入数据(入栈)或者从栈顶取出数据(出栈)。

栈的简单操作

栈的简单操作包括:

  1. 初始化栈
  2. 判断栈是否为空
  3. 判断栈是否已满
  4. 入栈操作
  5. 出栈操作
  6. 获取栈顶元素

栈的初始化

栈的初始化可以通过动态分配内存的方式来实现。代码如下:

#define MAXSIZE 100
typedef int ElemType;

typedef struct {
    ElemType data[MAXSIZE];  // 存放栈数据
    int top;  // 栈顶指针
} SqStack;

// 初始化栈
void InitStack(SqStack *S) {
    S->top = -1;  // 栈顶指针初始化为-1,表示栈为空
}

判断栈是否为空

栈是否为空可以通过栈顶指针判断。如果栈顶指针等于-1,表示栈为空,否则栈不为空。代码如下:

// 判断栈是否为空
int IsEmpty(SqStack S) {
    if (S.top == -1) {
        return 1;  // 栈为空
    }
    return 0;  // 栈不为空
}

判断栈是否已满

静态数组实现的栈可以通过数组下标来判断栈是否已满。如果栈顶指针等于MAXSIZE-1,表示栈已满,否则栈未满。代码如下:

// 判断栈是否已满
int IsFull(SqStack S) {
    if (S.top == MAXSIZE-1) {
        return 1;  // 栈已满
    }
    return 0;  // 栈未满
}

入栈操作

入栈操作是将一个元素压入栈顶。入栈操作需要先判断栈是否已满。如果栈未满,将元素插入到栈顶,并将栈顶指针加1。代码如下:

// 入栈操作
int Push(SqStack *S, ElemType x) {
    if (IsFull(*S)) {
        return 0;  // 栈已满,入栈失败
    }
    S->top++;  // 栈顶指针加1
    S->data[S->top] = x;  // 将元素压入栈顶
    return 1;  // 入栈成功
}

出栈操作

出栈操作是将栈顶元素弹出。出栈操作需要先判断栈是否为空。如果栈非空,将栈顶元素弹出,并将栈顶指针减1。代码如下:

// 出栈操作
int Pop(SqStack *S, ElemType *x) {
    if (IsEmpty(*S)) {
        return 0;  // 栈为空,出栈失败
    }
    *x = S->data[S->top];  // 将栈顶元素弹出
    S->top--;  // 栈顶指针减1
    return 1;  // 出栈成功
}

获取栈顶元素

获取栈顶元素是返回栈顶元素的值,但不弹出栈顶元素。获取栈顶元素需要先判断栈是否为空。如果栈非空,返回栈顶元素的值。代码如下:

// 获取栈顶元素
int GetTop(SqStack S, ElemType *x) {
    if (IsEmpty(S)) {
        return 0;  // 栈为空,获取栈顶元素失败
    }
    *x = S.data[S.top];  // 返回栈顶元素的值
    return 1;  // 获取栈顶元素成功
}

示例说明

示例1:用栈模拟简单计算器

现在有一个简单的计算器,只支持+、-、*、/四则运算,不支持括号,我们需要用栈来模拟它。假设用户输入的表达式存放在一个字符数组exp中,我们可以通过以下步骤来实现:

  1. 初始化栈S。
  2. 从左到右遍历exp,依次读取每个字符。
  3. 如果字符是数字字符,则将其转换为整数,并入栈S。
  4. 如果字符是操作符,则从栈S中弹出两个操作数,进行计算,将计算结果压入栈S。
  5. 最后栈顶就是表达式计算结果。

具体实现可以参考以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 100

typedef struct {
    int data[MAXSIZE];
    int top;
} SqStack;

void InitStack(SqStack *S) {
    S->top = -1;
}

int IsEmpty(SqStack S) {
    if (S.top == -1) {
        return 1;
    }
    return 0;
}

int IsFull(SqStack S) {
    if (S.top == MAXSIZE-1) {
        return 1;
    }
    return 0;
}

int Push(SqStack *S, int x) {
    if (IsFull(*S)) {
        return 0;
    }
    S->top++;
    S->data[S->top] = x;
    return 1;
}

int Pop(SqStack *S, int *x) {
    if (IsEmpty(*S)) {
        return 0;
    }
    *x = S->data[S->top];
    S->top--;
    return 1;
}

int GetTop(SqStack S, int *x) {
    if (IsEmpty(S)) {
        return 0;
    }
    *x = S.data[S.top];
    return 1;
}

int main() {
    SqStack S;
    InitStack(&S);
    char exp[MAXSIZE];
    printf("请输入表达式:");
    fgets(exp, MAXSIZE, stdin);
    int len = strlen(exp);
    int i, num1, num2, result;
    for (i = 0; i < len; i++) {
        if (exp[i] >= '0' && exp[i] <= '9') {  // 如果是数字字符
            int num = exp[i] - '0';
            Push(&S, num);
        } else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') {  // 如果是操作符
            Pop(&S, &num2);
            Pop(&S, &num1);
            switch (exp[i]) {  // 根据操作符进行计算
                case '+':
                    result = num1 + num2;
                    break;
                case '-':
                    result = num1 - num2;
                    break;
                case '*':
                    result = num1 * num2;
                    break;
                case '/':
                    result = num1 / num2;
                    break;
            }
            Push(&S, result);
        }
    }
    GetTop(S, &result);
    printf("计算结果:%d\n", result);
    return 0;
}

示例2:判断括号是否匹配

现在有一个括号字符串,我们需要用栈来判断其中的括号是否匹配。假设括号字符串存放在一个字符数组str中,我们可以通过以下步骤来实现:

  1. 初始化栈S。
  2. 从左到右遍历str,依次读取每个字符。
  3. 如果字符是左括号,入栈S。
  4. 如果字符是右括号,从栈S中弹出一个左括号,判断两者是否匹配。
  5. 遍历完成后,如果栈S非空,则括号不匹配,否则括号匹配。

具体实现可以参考以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 100

typedef struct {
    char data[MAXSIZE];
    int top;
} SqStack;

void InitStack(SqStack *S) {
    S->top = -1;
}

int IsEmpty(SqStack S) {
    if (S.top == -1) {
        return 1;
    }
    return 0;
}

int IsFull(SqStack S) {
    if (S.top == MAXSIZE-1) {
        return 1;
    }
    return 0;
}

int Push(SqStack *S, char x) {
    if (IsFull(*S)) {
        return 0;
    }
    S->top++;
    S->data[S->top] = x;
    return 1;
}

int Pop(SqStack *S, char *x) {
    if (IsEmpty(*S)) {
        return 0;
    }
    *x = S->data[S->top];
    S->top--;
    return 1;
}

int GetTop(SqStack S, char *x) {
    if (IsEmpty(S)) {
        return 0;
    }
    *x = S.data[S.top];
    return 1;
}

int main() {
    SqStack S;
    InitStack(&S);
    char str[MAXSIZE];
    printf("请输入括号字符串:");
    fgets(str, MAXSIZE, stdin);
    int len = strlen(str);
    int i;
    char ch, top;
    for (i = 0; i < len-1; i++) {
        ch = str[i];
        if (ch == '(' || ch == '[' || ch == '{') {  // 如果是左括号
            Push(&S, ch);
        } else if (ch == ')' || ch == ']' || ch == '}') {  // 如果是右括号
            if (IsEmpty(S)) {
                printf("括号不匹配\n");
                return 0;
            }
            Pop(&S, &top);
            if ((ch == ')' && top != '(') || (ch == ']' && top != '[') || (ch == '}' && top != '{')) {
                printf("括号不匹配\n");
                return 0;
            }
        }
    }
    if (!IsEmpty(S)) {
        printf("括号不匹配\n");
        return 0;
    }
    printf("括号匹配\n");
    return 0;
}

总结

本文主要介绍了栈(Stack)的基本概念和简单操作,包括栈的初始化、判断栈是否为空、判断栈是否已满、入栈操作、出栈操作、获取栈顶元素等。栈是一种非常常用的数据结构,它可以用于解决很多实际问题,例如用栈模拟计算器、用栈判断括号是否匹配等。通过本文的介绍,相信读者已经对栈有了更深入的了解,可以更加灵活地使用栈来解决实际问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之栈简单操作 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • Go 数据结构之二叉树详情

    Go 数据结构之二叉树详情 二叉树是一种树形数据结构,它的每个节点至多只有两个子节点,通常称为左子节点和右子节点。在本文中,我们将介绍二叉树的定义、遍历方法和常见应用场景。 定义 一个二叉树是一个有根树,它的每个节点最多有两个子节点,用左子树和右子树来区分。 在 Go 代码中,可以通过如下结构体定义表示二叉树的节点: type Node struct { L…

    数据结构 2023年5月17日
    00
  • JavaScript 处理树数据结构的方法示例

    下面是“JavaScript 处理树数据结构的方法示例”的完整攻略。 什么是树数据结构 树形数据结构是一种非常重要的数据结构,常被用于模拟现实中大量的层级结构。例如:文件目录、网站导航等。其是由一个根节点和若干个子节点构成的,每个节点可以有0个或多个子节点。 使用 JavaScript 处理树形数据结构 了解了树形数据结构后,我们可以使用 JavaScrip…

    数据结构 2023年5月17日
    00
  • 贪心算法基础及leetcode例题

    理论 本质:找到每个阶段的局部最优,然后去推导得到全局最优两个极端:常识&&很难: 很多同学通过了贪心的题目,但都不知道自己用了贪心算法,因为贪心有时候就是常识性的推导,所以会认为本应该就这么做! 套路:贪心没有套路,说白了就是常识性推导加上举反例做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。 贪心算法一般分为如下…

    算法与数据结构 2023年4月20日
    00
  • java 数据结构之栈与队列

    Java 数据结构之栈与队列 什么是栈? 栈是一种根据先进后出(LIFO)原则的数据结构,即最后压入的元素最先弹出。栈可以用数组或链表实现。栈的两个基本操作是 push(入栈)和 pop(出栈)。 栈的特性 只允许在栈的顶部插入和删除元素。 操作受限只能从一端进行。 元素的插入和删除时间复杂度都为 O(1)。 栈的示例 以下是使用 Java 语言实现栈的示例…

    数据结构 2023年5月17日
    00
  • C语言数据结构之二叉树详解

    C语言数据结构之二叉树详解 什么是二叉树? 二叉树是一种非常常用的数据结构,它具有以下几个特点: 在二叉树中,每个节点最多有两个子节点,其中一个称为左子节点,另一个称为右子节点。 每个节点都有一个值,这个值可以是任意类型的,比如整数、字符、指针等等。 可以使用递归的方式来遍历一个二叉树,具体包括前序遍历、中序遍历和后序遍历。 二叉树的存储方式 二叉树可以使用…

    数据结构 2023年5月17日
    00
  • C#数据结构与算法揭秘三 链表

    作为一本通俗易懂的C#数据结构与算法书籍,其第三章主要介绍链表(Linked List)的概念和基本操作。下面是链表的基本概念: 链表(Linked List)是一种动态数据结构,其中的元素按线性顺序排列,并且每个元素都称为一个结点(Node)。 每个结点都包含一个元素和一个指向下一个结点的指针(Pointer)。 相比于数组,链表的优势在于能够轻松地增加或…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之二叉树必会知识点总结

    Go语言数据结构之二叉树必会知识点总结 二叉树是一种非常重要的数据结构,它被广泛应用于算法、数据处理等领域。在Go语言中,使用二叉树可以实现很多高级数据结构和算法。本文将为大家介绍二叉树相关的基本知识和操作,以及如何利用Go语言实现二叉树。 什么是二叉树? 二叉树是一种树形结构,由一个根节点和两个子树组成。它的每个节点最多有两个子节点,称为左子节点和右子节点…

    数据结构 2023年5月17日
    00
  • Go语言数据结构之插入排序示例详解

    Go语言数据结构之插入排序示例详解 什么是插入排序? 插入排序是一种简单直观的排序方法,其基本思想是将一个待排序的序列分成已排序和未排序两部分,从未排序的部分中选择一个元素插入到已排序部分的合适位置,直到所有元素都被插入到已排序部分为止。 插入排序示例 示例1 我们来看一个数字序列的插入排序示例: package main import "fmt&…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部