C++小工修炼之路XVI(栈和队列,优先级队列)

mac2024-03-28  29

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

bool IsPopOrder(vector<int> pushV,vector<int> popV) { int i = 0; //两个数字来分别记录两个数组 int j = 0; stack<int> sta; //一个栈 while (i < (int)pushV.size()||j < popV.size()) //当第一个数组没遍历到头,或者第二个数组没遍历到头的时候就一直循环 { if (sta.empty()) //假如栈是空的就入栈 sta.push(pushV[i++]); //入栈之后i++ if (sta.top() != popV[j]) //假如栈顶元素和出栈序列的元素不相等 sta.push(pushV[i++]); //那就继续入栈 else //否则的话就是相等,相等的话就出栈 { j++; sta.pop(); } } if (i == pushV.size()&&j == popV.size())//出来之后假如 i走到了头,并且j走到了头那么就说明序列是正确的 return true; return false; } bool IsPopOrder(vector<int> pushV, vector<int> popV) { stack<int> sta; int index = 0; int outdex = 0; while (outdex < popV.size()) { while (sta.empty()|| sta.top() != popV[outdex]) { if (index < pushV.size()) { sta.push(pushV[index++]); } else { return false; } sta.pop(); outdex++; } } return true; }

逆波兰表达式求值:

string num2str(const int num){ //数字转字符串函数 stringstream ss; ss << num; return ss.str(); } int evalRPN(vector<string>& tokens) { stack<string> sta; int i = 0; while (i < tokens.size()) { if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") { if (tokens[i] == "+") { int left = atoi(sta.top().c_str()); sta.pop(); int right = atoi(sta.top().c_str()); sta.pop(); int res = right + left; string s = num2str(res); sta.push(s); i++; } else if (tokens[i] == "-") { int left = atoi(sta.top().c_str()); sta.pop(); int right = atoi(sta.top().c_str()); sta.pop(); int res = right - left; string s = num2str(res); sta.push(s); i++; } else if (tokens[i] == "*") { int left = atoi(sta.top().c_str()); sta.pop(); int right = atoi(sta.top().c_str()); sta.pop(); int res = right * left; string s = num2str(res); sta.push(s); i++; } else if (tokens[i] == "/") { int left = atoi(sta.top().c_str()); sta.pop(); int right = atoi(sta.top().c_str()); sta.pop(); int res = right / left; string s = num2str(res); sta.push(s); i++; } } else sta.push(tokens[i++]); } return atoi(sta.top().c_str()); }

最小栈三种解法:前面说过了

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。 层序遍历升级版

class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> que; vector<vector<int>> vv; que.push(root); if(root == nullptr) return vv; while(!que.empty()) { vector<int> v; int size = que.size(); for(int i = 0;i < size; ++i) { TreeNode* cur = que.front(); v.push_back(cur->val); if(que.front()->left) que.push(que.front()->left); if(que.front()->right) que.push(que.front()->right); que.pop(); } vv.push_back(v); } return vv; } };

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 类似于上面是 下面是 只需要在最后返回的时候使用reverse()函数即可,就是效率不咋高

reverse(vv.begin(),vv.end()); return vv;

priority_queue:优先级队列 堆:将集合中的数据保存在数组中(得到的以可完全二叉树) 完全二叉树 != 堆 默认的优先级队列式大堆,但是是可以修改的。

函数模板原型: template < class T, class Container = vector<T>,class Compare = less<typename Container::value_type> > class priority_queue; 可以看到第二个参数是一个数组,第三个参数是一个默认的比较方式是less ,<小于号,也就是说在元素比较的时 候,元素1 < 元素2,则交换元素,也就是说,大的 在上,小的在下,所以说默认情况下是大堆 #include<iostream> #include<queue> using namespace std; #include<functional> int main() { priority_queue<int> q1; q1.push(1); q1.push(2); q1.push(3); q1.push(4); q1.push(5); vector<int> v1{ 1, 2, 3, 4, 5 }; priority_queue<int> q2(v1.begin(), v1.end()); priority_queue<int, vector<int>, greater<int>> q3(v1.begin(),v1.end()); cout << q1.top() << endl << q2.top() << endl << q3.top() << endl; return 0;

要想按照大堆的方式打印的话就必须要,将参数列表中的三个参数全部给出来

自定义类型的变量要想存到优先级队列里面的时候必须要,自己重载比较方法。重载< (大堆),重载>(小堆)

最新回复(0)