棧和佇列的應用
阿新 • • 發佈:2019-01-25
棧 佇列作為特殊的線性表,應用相當廣泛。一般有遞迴、括號匹配、中綴表示式轉字尾表示式、字尾表示式求值、以及樹的層次遍歷等幾個應用方面。以下給出了幾個例子供讀者自行研讀。
1、遞迴
以下給出斐波那切數列計算的例子供參考。
/** \brief 棧在遞迴中的呼叫 * * \param * \param * \return * */ #include <iostream> #include <stack> using namespace std; int Fib(int n) { /** \brief output shows the sequence that is preorder process. * * \param * \param * \return * */ cout<<"Fib"<<n<<" is called!"<<endl; if(n==0) return 0; else if(n==1) return 1; else return Fib(n-1)+Fib(n-2); } int main() { cout << "------------Hello world!-------------" << endl; cout<<Fib(5); return 0; }
2、括號匹配
典型的棧的應用,可以判斷表示式是否合法。
#include <iostream> #include <string.h> #include <stdlib.h> #include <stack> using namespace std; bool khpp(char str[],int n) { int i=0; stack<char> s; while(i<n) { switch(str[i]) { case '(': s.push(str[i]); break; case '{': s.push(str[i]); break; case '[': s.push(str[i]); break; case ')': if(!s.empty() && s.top()=='(') { s.pop(); } else { i=100000; } break; case ']': if(!s.empty() && s.top()=='[') { s.pop(); } else { i=100000; } break; case '}': if(!s.empty() && s.top()=='{') { s.pop(); } else { i=100000; } break; } i++; } //cout<<"i="<<i<<endl; if(s.empty() && i==n) { return true; } else return false; } int main() { char str[20]; cout << "------------Hello world!-------------" << endl; cin>>str; if(khpp(str,strlen(str))) cout<<"OK!"<<endl; else cout<<"NG!"<<endl; return 0; }
3、中綴表示式轉字尾表示式
實際運算子太多,這裡只是以+-*/%()作為例子。字尾表示式求值也是如此。
#include <iostream> #include <stack> #include <string.h> using namespace std; void printStack(stack<char> s) { while(!s.empty()) { cout<<s.top()<<" "; s.pop(); } cout<<endl; } void strzh(char str[],int n,char zhstr[]) { int i=0,j=0; stack<char> s; for(i=0;i<n;i++) { if(str[i]>=48 && str[i]<=57) { zhstr[j]=str[i]; j++; } else { switch(str[i]) { case '(': { s.push(str[i]); break; } case ')': { while(s.top()!='(') { zhstr[j]=s.top(); s.pop(); j++; } s.pop(); break; } case '+': { while(!s.empty() && (s.top()=='+' || s.top()=='-' || s.top()=='*' || s.top()=='/')) { zhstr[j]=s.top(); s.pop(); j++; } s.push(str[i]); break; } case '-': { while(!s.empty() && (s.top()=='+' || s.top()=='+' || s.top()=='-' || s.top()=='*' || s.top()=='/')) { zhstr[j]=s.top(); s.pop(); j++; } s.push(str[i]); break; } case '*': { while(!s.empty() && (s.top()=='*' || s.top()=='/')) { zhstr[j]=s.top(); s.pop(); j++; } s.push(str[i]); break; } case '/': { while(!s.empty() && (s.top()=='*' || s.top()=='/')) { zhstr[j]=s.top(); s.pop(); j++; } s.push(str[i]); break; } } } //printStack(s); } while(!s.empty()) { zhstr[j]=s.top(); s.pop(); j++; } } int main() { char str[20]; char zhstr[20]={0}; cin>>str; strzh(str,strlen(str),zhstr); cout<<zhstr<<endl; return 0; }
4、字尾表示式求值
#include <iostream>
#include <stack>
#include <string.h>
using namespace std;
int solve(char str[],int n)
{
stack<int> s;
int i=0;
while(i<n)
{
if(48<=str[i] && str[i]<=57)
{
s.push(str[i]-48);
}
else
{
int top1=s.top();
s.pop();
int top2=s.top();
s.pop();
switch(str[i])
{
case '+':
s.push(top2+top1);
break;
case '-':
s.push(top2-top1);
break;
case '*':
s.push(top2*top1);
break;
case '/':
s.push(top2/top1);
break;
case '%':
s.push(top2%top1);
break;
}
}
cout<<"i="<<i<<" "<<"top="<<s.top()<<endl;
i++;
}
return s.top();
}
int main()
{
char str[30];
cout << "--------------------Hello world!---------------" << endl;
cin>>str;
cout<<solve(str,strlen(str));
return 0;
}
5、層次遍歷
層次遍歷可以結合本人前邊二叉樹的儲存以及遍歷方法的幾篇文章仔細研讀。
/** \brief 佇列在二叉樹層次遍歷中的應用
*
* \param
* \param
* \return
*
*/
#include <iostream>
#include <queue>
#include "ThreadTree.h"
using namespace std;
void visit1(ThreadTree p)
{
cout<<p->data<<" ";
}
void LayotOrder(ThreadTree T)
{
queue<ThreadTree> que;
ThreadTree p;
que.push(T);
while(!que.empty())
{
p=que.front();
que.pop();
visit1(p);
if(p->lchild!=NULL)
{
que.push(p->lchild);
}
if(p->rchild!=NULL)
{
que.push(p->rchild);
}
}
}
int main()
{
cout << "---------------Hello world!--------------" << endl;
ThreadTree T;
T=Init_ThreadTree();
LayotOrder(T);
return 0;
}