C语言栈顺序结构实现代码

下面我将详细讲解如何用 C 语言实现栈的顺序结构并提供两个示例。

什么是栈?

栈是一种数据结构,特点是 Last In First Out (LIFO) 后进先出。栈具有两个基本操作:压入(push)和弹出(pop)。在栈的顺序结构中,栈被定义为一个固定大小的数组,其中有一个指针(top)指向栈的顶部元素。

栈的顺序结构实现

  1. 首先,我们需要定义栈的数据结构,包括栈的大小和栈顶指针。
#define MAXSIZE 100 // 栈的大小

typedef struct {
  int data[MAXSIZE];
  int top;
} Stack;
  1. 接下来,我们需要定义一些基本的操作函数,如 push 和 pop 。
// 初始化栈
void InitStack(Stack* s) {
  s->top = -1;
}

// 判断栈是否为空
int IsEmpty(Stack* s) {
  return s->top == -1;
}

// 判断栈是否已满
int IsFull(Stack* s) {
  return s->top == MAXSIZE - 1;
}

// 入栈
int Push(Stack* s, int x) {
  if (IsFull(s)) {
    return 0; // 栈已满
  }
  s->top++;
  s->data[s->top] = x;
  return 1;
}

// 出栈
int Pop(Stack* s, int* x) {
  if (IsEmpty(s)) {
    return 0; // 栈已空
  }
  *x = s->data[s->top];
  s->top--;
  return 1;
}

示例一:括号匹配

括号匹配是栈的基本应用之一。我们可以使用栈来检查字符串中的括号是否匹配。具体做法是将左括号压入栈中,遇到右括号时弹出栈顶元素,并检查其是否是对应的左括号。

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

int IsPair(char left, char right) {
  if (left == '(' && right == ')') {
    return 1;
  }
  if (left == '[' && right == ']') {
    return 1;
  }
  if (left == '{' && right == '}') {
    return 1;
  }
  return 0;
}

int CheckParentheses(char* s) {
  Stack stk;
  InitStack(&stk);
  for (int i = 0; i < strlen(s); i++) {
    if (s[i] == '(' || s[i] == '[' || s[i] == '{') {
      Push(&stk, s[i]);
    } else if (s[i] == ')' || s[i] == ']' || s[i] == '}') {
      int x;
      if (Pop(&stk, &x) == 0 || IsPair(x, s[i]) == 0) {
        return 0;
      }
    }
  }
  return IsEmpty(&stk) ? 1 : 0;
}

int main() {
  char* s1 = "{(a+b)*(c+d)}";
  char* s2 = "[[[(a+b)*(c+d])]]";
  char* s3 = "{(a+b)*(c+d]))";

  printf("%s: %d\n", s1, CheckParentheses(s1));
  printf("%s: %d\n", s2, CheckParentheses(s2));
  printf("%s: %d\n", s3, CheckParentheses(s3));

  return 0;
}

以上程序输出结果为:

{(a+b)*(c+d)}: 1
[[(a+b)*(c+d)]]: 1
{(a+b)*(c+d])): 0

示例二:中缀表达式求值

中缀表达式是指二元运算符出现在操作数之间的表达式,如 3 + 4。我们可以使用栈来求解中缀表达式。

具体做法是维护两个栈,一个用于操作符,一个用于操作数。当遇到操作数时,将其压入操作数栈中;当遇到操作符时,比较操作符与操作符栈栈顶元素的优先级。如果操作符优先级大于栈顶操作符,则将其压入栈中;否则,弹出栈顶元素计算并将结果压入操作数栈中。当表达式扫描完成后,操作符栈中剩余的操作符应全部弹出并计算。

#include <stdio.h>

int GetPriority(char oper) {
  if (oper == '(' || oper =='[' || oper == '{') {
    return 0;
  }
  if (oper == '+' || oper == '-') {
    return 1;
  }
  if (oper == '*' || oper == '/') {
    return 2;
  }
  return -1;
}

double Calculate(double a, double b, char oper) {
  switch (oper) {
    case '+': return a + b;
    case '-': return a - b;
    case '*': return a * b;
    case '/': return a / b;
    default: return 0;
  }
}

double EvalInfixExpression(char* expr) {
  Stack opers, nums;
  InitStack(&opers);
  InitStack(&nums);
  for (int i = 0; i < strlen(expr); i++) {
    if (expr[i] >= '0' && expr[i] <= '9') {
      double x = 0;
      int j = i;
      while (j < strlen(expr) && expr[j] >= '0' && expr[j] <= '9') {
        x = x * 10 + (expr[j] - '0');
        j++;
      }
      i = j - 1;
      Push(&nums, x);
    } else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/') {
      while (!IsEmpty(&opers) && GetPriority(expr[i]) <= GetPriority(opers.data[opers.top])) {
        double b, a;
        Pop(&nums, &b);
        Pop(&nums, &a);
        char oper;
        Pop(&opers, &oper);
        double result = Calculate(a, b, oper);
        Push(&nums, result);
      }
      Push(&opers, expr[i]);
    } else if (expr[i] == '(' || expr[i] == '[' || expr[i] == '{') {
      Push(&opers, expr[i]);
    } else if (expr[i] == ')' || expr[i] == ']' || expr[i] == '}') {
      while (!IsEmpty(&opers) && opers.data[opers.top] != '(' && opers.data[opers.top] != '[' && opers.data[opers.top] != '{') {
        double b, a;
        Pop(&nums, &b);
        Pop(&nums, &a);
        char oper;
        Pop(&opers, &oper);
        double result = Calculate(a, b, oper);
        Push(&nums, result);
      }
      char left;
      Pop(&opers, &left);
    }
  }
  while (!IsEmpty(&opers)) {
    double b, a;
    Pop(&nums, &b);
    Pop(&nums, &a);
    char oper;
    Pop(&opers, &oper);
    double result = Calculate(a, b, oper);
    Push(&nums, result);
  }
  double result;
  Pop(&nums, &result);
  return result;
}

int main() {
  char* expr1 = "1+2*3-4/2";
  char* expr2 = " 2 * ( 3 + 4 / ( 1 + 2 ) ) ";
  printf("%s = %.2lf\n", expr1, EvalInfixExpression(expr1));
  printf("%s = %.2lf\n", expr2, EvalInfixExpression(expr2));
  return 0;
}

以上程序输出结果为:

1+2*3-4/2 = 5.00
 2 * ( 3 + 4 / ( 1 + 2 ) )  = 8.00

这就是我们使用 C 语言实现栈的顺序结构的完整攻略,希望能对你有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言栈顺序结构实现代码 - Python技术站

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

相关文章

  • 在C++中如何阻止类被继承详解

    在C++中,如果想要阻止某个类被继承,可以使用以下两种方法。 使用final关键字 在C++11标准中,引入了final关键字,可以用于修饰类、函数和变量,表示它们是最终版本,不允许子类、派生函数和别名修改。如果将一个类声明为final,则它不可以被其他类继承。 示例代码: class Base final { // 将Base类声明为final,不可以被继…

    C 2023年5月23日
    00
  • VSCode各语言运行环境配置方法示例详解

    下面我会为你详细讲解 “VSCode各语言运行环境配置方法示例详解”的完整攻略。 概述 在使用 Visual Studio Code 进行编程开发时,不同的语言需要不同的运行环境。本篇攻略将会详细讲解如何配置 VSCode 的运行环境。 步骤 步骤一:安装与配置相应的编程语言环境 首先确定你需要使用的编程语言,然后安装相应的运行环境。以 Node.js 为例…

    C 2023年5月23日
    00
  • 解读C++编译报错有迹可寻

    下面是“解读C++编译报错有迹可寻”的完整攻略,包含以下内容: 1. 什么是编译报错 在编写 C++ 程序时,由于语法、类型、函数调用等方面出现问题会导致编译失败,此时编译器会给出一个错误提示,我们称之为编译报错。编译报错是程序员最常见的错误类型之一,在进行调试时,要仔细分析编译报错信息找出错误所在。 2. 如何解读编译报错 一般来说,编译报错信息由以下部分…

    C 2023年5月23日
    00
  • C 程序 查找给定范围内的回文数

    C 程序 查找给定范围内的回文数题目是一个比较典型简单的回文数算法题,可以通过C语言编程实现。 下面是C程序实现查找回文数的完整使用攻略: 1. 确定算法和数据结构 题目要求查找给定范围内的回文数,所以可以选择使用“回文数判断算法”对给定的范围内的数逐一进行判断。 判断给定数x是否为回文数的算法可以用以下方式: 将这个数每一位上的数字存储到数组中(例如,数字…

    C 2023年5月9日
    00
  • python访问纯真IP数据库的代码

    Python访问纯真IP数据库的代码完整攻略 纯真IP数据库是一款用于IP地址查询的软件,可以通过输入一个IP地址来查询对应的区域、省份、城市等信息。在Python中,可以通过访问纯真IP数据库来实现这一功能。下面是实现该功能的完整攻略。 步骤一:下载纯真IP数据库 首先需要从纯真官网下载最新版纯真IP数据库,下载后,解压压缩包,可以得到一个名为“QQWry…

    C 2023年5月23日
    00
  • 解析C++中指向对象的指针使用

    当我们需要使用C++中的指针来对一个对象进行操作时,需要使用指向对象的指针。 以下是可以用来解析C++中指向对象的指针使用的攻略: 1. 创建指向对象的指针 指向对象的指针是一个存储对象地址的变量,指针变量具有自己的地址和类型,它可以为一个类的实例分配并且可以通过调用类成员函数来操作对象。 指向对象的指针有时候被称为“该对象的指针”。通常,创建指向对象的指针…

    C 2023年5月22日
    00
  • json简单介绍

    下面我来为你详细讲解关于“JSON简单介绍”的完整攻略。 什么是JSON? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它采用类似于 JavaScript 对象字面量的语法,易于人阅读和编写,同时也易于机器解析和生成。JSON是一种文本格式,可以被任何编程语言解析和生成,不依赖于任何语言环境。 JSON的语法规…

    C 2023年5月23日
    00
  • 阿里面试必会的20道C++面试题与参考答案解析

    当提到C++面试题时,涉及到的题目类型与难度可能非常广泛。针对阿里面试常见的C++面试题,以下提供了20道必会的题目及相应的参考答案解析。 1. 求100以内所有奇数的和,使用while循环实现 #include <iostream> using namespace std; int main() { int sum = 0; int i = 1…

    C 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部