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

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日

相关文章

  • C++数据结构之AVL树的实现

    C++数据结构之AVL树的实现 什么是AVL树 AVL树是一种自平衡二叉查找树,也就是说它通过旋转操作来保持树的平衡。 在AVL树中,任何节点的两个子树高度差不超过1。如果高度差大于1,则需要通过旋转操作来调整树的平衡。 AVL树提供了比红黑树更快的插入和删除操作,但是在读取数据时红黑树更快。 AVL树的实现 结构体定义 我们可以先定义一个结构体来表示AVL…

    数据结构 2023年5月17日
    00
  • C++数据结构之双向链表

    C++数据结构之双向链表完整攻略 1. 什么是双向链表 双向链表是一种特殊的链表结构,每个节点拥有两个指针域,分别指向前继和后继节点。 双向链表不需要像单向链表那样从头到尾遍历整个链表,可以通过前后指针直接访问前后节点,提高了查找、删除、插入等操作的效率。 双向链表有一些常用的操作,如插入节点、删除节点、查找节点等。 2. 双向链表的实现 2.1 节点定义 …

    数据结构 2023年5月17日
    00
  • C语言数据结构之复杂链表的拷贝

    C语言数据结构之复杂链表的拷贝 什么是复杂链表 在了解如何拷贝复杂链表之前,首先需要知道什么是复杂链表。复杂链表是由多个节点组成的链表,每个节点除了包含普通链表节点的值和指向下一个节点的指针外,还包含一个指向链表中的任意一个节点的指针。因此,每个节点有两个指针:一个指向下一个节点,一个指向任意一个节点。 复杂链表示意图如下: +—+ +—+ +—…

    数据结构 2023年5月17日
    00
  • 【ACM算法竞赛日常训练】DAY4题解与分析【树】【子序列】| 组合数学 | 动态规划

    DAY4共2题: 树(组合数学) 子序列(dp,数学) ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 原文链接(阅读原文获得更好阅读体验):https://www.eriktse.com/algorithm/109…

    算法与数据结构 2023年4月18日
    00
  • C语言数据结构实现字符串分割的实例

    C语言中数据结构实现字符串分割可以用到两种常见数据结构:指针和数组。 方法一:指针 步骤一:创建指针 首先声明一个指针类型的变量,用来存储字符串中单个字符所在的地址: char *ptr; 步骤二:遍历字符串 通过对字符串进行遍历,在每个分隔符位置上获取单词,并通过指针记录下每个单词的地址: char str[] = "C语言-数据结构-字符串分割…

    数据结构 2023年5月17日
    00
  • 数据结构 C语言实现循环单链表的实例

    首先,在开始讲解数据结构中循环单链表的实现前,需要明确循环单链表的概念以及其与单链表的区别。 循环单链表是一种链式存储结构,与单链表不同的是,在循环单链表的尾部也可以指向链表的头部,形成一个环。因此,我们可以通过尾部的指针来遍历整个循环单链表。 接下来,为了方便理解和学习,我们将使用C语言来实现循环单链表的实例。下面分几个步骤来讲解。 1. 定义结构体和创建…

    数据结构 2023年5月17日
    00
  • 【牛客小白月赛69】题解与分析A-F【蛋挞】【玩具】【开题顺序】【旅游】【等腰三角形(easy)】【等腰三角形(hard)】

    比赛传送门:https://ac.nowcoder.com/acm/contest/52441 感觉整体难度有点偏大。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 个人博客:www.eriktse.com A-蛋…

    算法与数据结构 2023年4月18日
    00
  • C++数据结构之哈希表的实现

    以下是详细的讲解: C++数据结构之哈希表的实现 哈希表的概念 哈希表是一种能够实现快速查找的散列表,通过将关键字映射到哈希表中的一个位置来实现快速查找。哈希表的查询、删除时间复杂度为O(1),操作效率非常高,所以常常被用来对大量数据进行检索。 哈希表的实现 哈希函数 哈希函数的主要作用就是将任意长度的输入数据转化为固定长度的散列值,一般采用对关键字进行取模…

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