資料結構-棧和佇列的應用(驗證括號的正確性,表示式求值,層次遍歷)
阿新 • • 發佈:2021-01-23
棧和佇列的應用
棧的應用
驗證括號的正確性
題目很簡單就是輸入一串字元,判斷字元中的括號是否合法。直接上程式碼:
#include <iostream>
#include <string.h>
using namespace std;
typedef char ElemType;
#define MAXSIZE 100
typedef 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]);
}//元素若為},),]則出棧 賦值給right
if ((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;
}
實驗結果:
表示式求值
要求一個表示式的結果,例如 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 stack
stack <char> OPTR; // Operator stack
OPTR.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;
}
實驗結果:
佇列的應用
層次遍歷
利用佇列儲存每一層的結點,再儲存到陣列中,很容易理解。下面是套路:
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;
}
佇列在計算機系統中的應用
一、解決主機與外部裝置之間速度不匹配的問題。
二、解決由多使用者引起的資源競爭問題。
如果覺得本文對你有幫助的話,不妨關注作者一波,小小的關注其實對我很重要。更多高質量內容與資料請訪問:資料結構簡單學,個人主頁:修心的小屋
如果喜歡的話,不妨關注一波,謝謝啦。