数据结构-栈和队列的应用(验证括号的正确性,表达式求值,层次遍历)

本文主要是介绍数据结构-栈和队列的应用(验证括号的正确性,表达式求值,层次遍历),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

栈和队列的应用

  栈的应用

  验证括号的正确性

  题目很简单就是输入一串字符,判断字符中的括号是否合法。直接上代码:

#include <iostream>
#include <string.h>
using namespace std;typedef char ElemType;
#define MAXSIZE 100typedef struct Stack
{ElemType data[MAXSIZE];int top;
}Stack;void InitStack(Stack& S) {S.top = -1;
}bool StackEmpty(Stack S) {if (S.top == -1) {return true;}return false;
}bool Push(Stack& S, ElemType x) {if (S.top == MAXSIZE - 1) {return false;}S.top++;S.data[S.top] = x;return true;
}
bool Pop(Stack& S, ElemType& x) {if (S.top == -1) {return false;}x = S.data[S.top];S.top--;return true;
}ElemType GetTop(Stack S) {return S.data[S.top];
}int main() {Stack S;InitStack(S);string str;cin >> str;//flag标志状态 true为括号匹配,false为不匹配bool flag = true;for (int i = 0; i < str.size(); i++) {//元素若为{,(,[则入栈if ((str[i] == '{') || (str[i] == '[') || (str[i] == '(')) {Push(S, str[i]);}//元素若为},),]则出栈 赋值给rightif ((str[i] == '}') || (str[i] == ']') || (str[i] == ')')) {if ((str[i] == '}' && GetTop(S) == '{') || (str[i] == ']' && GetTop(S) == '[') || (str[i] == ')' && GetTop(S) == '(')) {char top = Pop(S, top);continue;}else {Push(S, str[i]);}}}if (S.top != -1) {    //当栈不为空时flag = false;}if (flag == false) {cout << "括号不匹配!" << endl;}else cout << "括号匹配!" << endl;system("pause");return 0;
}

  实验结果:

image-20210122155026920

image-20210122155116917

  表达式求值

  要求一个表达式的结果,例如 9 +(3 - 1) * 3 + 1 ,我们可以直接算出来,但是计算机不会,计算机一般将这种表达式转换成后缀表达式,运算符在操作数后面,并且运算也是根据优先级排列好的,没有括号,利于计算机的计算,如上述表达式转换为后缀表示式为:

9 3 1 - 3 * 10 + ,但是我们现在要实现的是中缀表达式的求值。计算思路:

  • 使用两个栈,stack0用于存储操作数,stack1用于存储操作符
  • 从左往右扫描,遇到操作数入栈stack0
  • 遇到操作符时,如果优先级低于或等于栈顶操作符优先级,则从stack0弹出两个元素进行计算,并压入stack0,继续与栈顶操作符的比较优先级
  • 如果遇到操作符高于栈顶操作符优先级,则直接入栈stack1
  • 遇到左括号,直接入栈stack1,遇到右括号,则直接出栈并计算,直到遇到左括号
//算符优先法
#include<iostream>
#include<cstring>
#include<stack>
using namespace std;  
const int maxn=110; 
char priority[7][7]={ {'>','>','<','<','<','>','>'},  {'>','>','<','<','<','>','>'},  {'>','>','>','>','<','>','>'},  {'>','>','>','>','<','>','>'},  {'<','<','<','<','<','=','0'},   // 此行"("=")"表示左右括号相遇,括号内运算已完成 {'>','>','>','>','0','>','>'},  {'<','<','<','<','<','0','='}    // "=" 表示整个表达式求值完毕 };                               //  "0"表示不可能出现这种情况 ( 语法错误 ) //Precede 用于判断运算符栈栈顶运算符 a1 与读入运算符 a2 之间的优先关系函数 
char Procede(char a,char b){   // 建立 pre[][] 到 运算符间的映射关系 int i,j;  switch(a){  case'+':i=0;break;  case'-':i=1;break;  case'*':i=2;break;  case'/':i=3;break;  case'(':i=4;break;  case')':i=5;break;  case'#':i=6;break;   // # 是表达式的结束符 }  switch(b){  case'+':j=0;break;  case'-':j=1;break;  case'*':j=2;break;  case'/':j=3;break;  case'(':j=4;break;  case')':j=5;break;  case'#':j=6;break;  }  return priority[i][j];  
}int Operate(int m,int n,char x){  if(x=='+')  return m+n;  if(x=='-')  return n-m;  if(x=='*')  return m*n;  if(x=='/')  return n/m;  
}  
// EvaluuateExpression-reduced
int main(){stack <int> OPND;  // Operand stackstack <char> OPTR;  // Operator stackOPTR.push('#');//char ss[2]="#";//尾部有\0 char s[maxn];cin>>s;strcat(s,ss);// 运算式尾部加 "#"--结束运算符 char c=s[0];int k=1;while(c!='#'||OPTR.top()!='#'){  //表达式未读完或者运算未完 int y=0;  if(c>='0'&&c<='9'){    while(c>='0'&&c<='9'){  // 读入连续的数字 y=y*10+(c-'0');  c=s[k++];  }  OPND.push(y);  // 把读进的数字入数字栈 }else{switch(Procede(OPTR.top(),c))  {  case'<':  //栈顶元素优先权低 OPTR.push(c);  c=s[k++];  break;  case'=':  OPTR.pop();  // 脱括号 c=s[k++];  // 读入下一个字符 break;  case'>':  //退栈并将运算结果入栈 char x=OPTR.top();OPTR.pop();  int m=OPND.top();OPND.pop();  int n=OPND.top();OPND.pop();  OPND.push(Operate(m,n,x));  break;    } }}cout<<OPND.top();return 0;
}

  实验结果:

image-20210122155312932

  队列的应用

  层次遍历

  利用队列存储每一层的结点,再存储到数组中,很容易理解。下面是套路:

vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> q;if (root != nullptr)   q.push(root);vector<vector<int>> res;while (!q.empty()) {int sz = q.size();vector<int> temp;for (int i = 0; i < sz; i++) {TreeNode* cur = q.front();q.pop();temp.push_back(cur->val);if (cur->left != nullptr)q.push(cur->left);if (cur->right != nullptr)q.push(cur->right);}res.push_back(temp);}return res;
}

  队列在计算机系统中的应用

  一、解决主机与外部设备之间速度不匹配的问题。

  二、解决由多用户引起的资源竞争问题。

如果觉得本文对你有帮助的话,不妨关注作者一波,小小的关注其实对我很重要。更多高质量内容与资料请访问:数据结构简单学,个人主页:修心的小屋
如果喜欢的话,不妨关注一波,谢谢啦。
在这里插入图片描述

这篇关于数据结构-栈和队列的应用(验证括号的正确性,表达式求值,层次遍历)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/652908

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#