二叉树_表达式计算_重要!!!.cpp
四则运算表达式可用表达式树来表达,如图所示。 图中最右边部分是该表达式树的后序遍历(后序遍历是指先遍历左子树,再遍历右子树,最后访问节点本身,简写 LRN)。
输入样例 1 复制
9,3,5,-,2,*,+
输出样例 1
5
// 字符串二叉树
struct TreeNodeStr {
string val;
TreeNodeStr *left;
TreeNodeStr *right;
TreeNodeStr() : val(0), left(nullptr), right(nullptr)
{}
TreeNodeStr(string x) : val(x), left(nullptr), right(nullptr)
{}
TreeNodeStr(string x, TreeNodeStr *left, TreeNodeStr *right) : val(x), left(left), right(right)
{}
};
// 数字二叉树
struct TreeNodeNum {
string val;
TreeNodeNum *left;
TreeNodeNum *right;
TreeNodeNum() : val(0), left(nullptr), right(nullptr)
{}
TreeNodeNum(int x) : val(x), left(nullptr), right(nullptr)
{}
TreeNodeNum(int x, TreeNodeNum *left, TreeNodeNum *right) : val(x), left(left), right(right)
{}
};
// 需要逆序通过stack构造树
// 逆序,根节点,右节点再左节点
TreeNodeStr *CreateCaculateTree(stack<string> &exprs, TreeNodeStr *node)
{
TreeNodeStr *root = nullptr;
string v = exprs.top();
exprs.pop();
if (node == nullptr) {
root = new TreeNodeStr(v);
}
if (v == "+" || v == "-" || v == "*" || v == "/") {
root->right = CreateCaculateTree(exprs, root->right);
root->left = CreateCaculateTree(exprs, root->left);
}
return root;
}
int OperateResult(int i, int j, char oper)
{
switch (oper) {
case '+':
return i + j;
case '-':
return i - j;
case '*':
return i * j;
case '/':
return i / j;
}
return 0;
}
int CaculateResult(TreeNodeStr *root)
{
int result;
string v = root->val;
if (v != "+" && v != "-" && v != "*" && v != "/") {
return stoi(root->val);
}
int left = CaculateResult(root->left);
int right = CaculateResult(root->right);
result = OperateResult(left, right, (root->val)[0]);
//cout << "root=" << v << ";result=" << result << endl;
return result;
}
stack<string> SplitExpress(const string &expression, const char *split)
{
stack<string> splits;
string v = expression + split;
string tmp = "";
for (char c : v) {
if (c == ',') {
splits.emplace(tmp);
tmp.clear();
} else {
tmp += c;
}
}
return splits;
}
int CalcExpression(const string &expression)
{
int result = 0;
stack<string> exprs = SplitExpress(expression, ",");
TreeNodeStr *root = CreateCaculateTree(exprs, nullptr);
result = CaculateResult(root);
return result;
}
// 大佬解法(以后有时间回头看)
// 泛函数 + 数字栈
static int CalcExpression(const string &expression)
{
stack<int> ce;
string s;
unordered_map<char, function<int(int, int)>> es{{'+', plus<int>()},
{'-', minus<int>()},
{'*', multiplies<int>()},
{'/', divides<int>()}};
for (char e: expression)
if (e == ',') {
if (isdigit(s.back()))
ce.emplace(stoi(s));
else {
int i = ce.top();
ce.pop();
ce.top() = es[s.front()](ce.top(), i);
}
s.clear();
} else
s += e;
if (ce.empty())
return stoi(s);
int result = ce.top();
ce.pop();
return es[s.front()](ce.top(), result);
}
二叉树_层遍历.cpp
取出二叉树所有元素
// 通过queue按从上到下,从做到右取出二叉树每一行
class Solution {
public:
bool isUnivalTree(TreeNode* root) {
set<int> st;
queue<TreeNode*> q; // 通过栈或队列
q.push(root);
while (!q.empty()) { // 队列里面是多个节点指针,不能通过q != nullptr/!q判空
TreeNode* node = q.front();
st.insert(node->val);
q.pop();
if(node->left) {
q.push(node->left);
}
if(node->right) {
q.push(node->right);
}
}
return st.size() == 1;
}
};
/*
1、确定叶子节点
叶子节点就是两个子节点都是 null 的节点,判断条件如下
if (cur.left == null && cur.right == null)
2、二叉树BFS核心思想
while循环对应每一层
for循环对应每一层从左到右
*/
// 二叉树的每一层
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
vector<int> vec;
~~for (int i = 0; i < que.size(); i++) {~~ // 这里没有理解??改行之前的写法,错误
int rowSize = que.size(); // 变量必须单独一行定义,这样for循环遍历时,长度是固定的,不会应为que在下面加入元素导致长度发现变化
for (int i = 0; i < rowSize; i++) {
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val); // 加入根节点的同时,子节点插入queue
if (node->left) {
que.push(node->left); // 这里新插入了元素,下一次for循环,queue的size在变化???
}
if (node->right) {
que.push(node->right);
}
}
result.push_back(vec);
}
return result;
}
// N叉树
vector<vector<int>> levelOrder(Node* root) {
queue<Node*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> vec;
for (int i = 0; i < size; i++) {
Node* node = que.front();
que.pop();
vec.push_back(node->val);
for (int i = 0; i < node->children.size(); i++) { // 将节点孩子加入队列
if (node->children[i]) {
que.push(node->children[i]);
}
}
}
result.push_back(vec);
}
return result;
}
二叉树_合并.cpp
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == nullptr) {
return t2;
}
if (t2 == nullptr) {
return t1;
}
auto merged = new TreeNode(t1->val + t2->val);
merged->left = mergeTrees(t1->left, t2->left);
merged->right = mergeTrees(t1->right, t2->right);
return merged;
}
二叉树_数组创建二叉树.cpp
TreeNode *Create_Tree(vector<int> &nums, int i) //层次遍历创建二叉树
{
if (nums[i] == 0 || i >= nums.size())
return nullptr;
TreeNode *root = new TreeNode(nums[i]);
root->left = Create_Tree(nums, i * 2);
root->right = Create_Tree(nums, i * 2 + 1);
return root;
}
二叉树_所有路径.cpp
// 获取路径数组
void getPaths(TreeNode*root, vector<int> path, vector<vector<int>>& paths)
{
if(!root) {
return paths;
}
path.push_back(root->val);
if(!root->left && !root->right) //如果到叶节点
{
paths.push_back(path);
return;
}
getPaths(root->left, path); //继续递归
getPaths(root->right, path);
}
vector<vector<int>> paths;
vector<int> path;
getPaths(root, path, paths); // 传空数组
return paths;
// 获取路径字符串
void getPaths(TreeNode*root, string path, vector<string>& paths)
{
if(!root) {
return paths;
}
path += to_string(root->value);
if(!root->left && !root->right) //如果到叶节点
{
paths.push_back(path);
return;
}
getPaths(root->left, path, paths); //继续递归
getPaths(root->right, path, paths);
}
vector<string> paths;
getPaths(root, "", paths); // 传空路径,递归遍历结束后将路径字符串存入paths
return paths;
二叉树_无节点_数字最多的层和对应层数.cpp
输入
第一行一个整数 N 表示销售负责人总数,取值范围:[1,100)。
第二行一个整数 M (0 <= M < N)表示有下属的负责人的人数。
随后 M 行,每行给出一位负责人,格式为ID K ID[1] ID[2] ... ID[K],其中 ID 是该负责人的代号,K (K > 0) 是其下属人数,后面给出的其下属们的代号。
最后一行给出待统计的指定负责人的代号ID
输出
两个数字,依次表示指定负责人名下人数最多的层级,及该层级的人数。
样例
输入样例 1 复制
23
13
21 1 23
01 4 03 02 04 05
03 3 06 07 08
06 2 12 13
13 1 21
08 2 15 16
02 2 09 10
11 2 19 20
17 1 22
05 1 11
07 1 14
09 1 17
10 1 18
01
输出样例 1
[4 9]
提示样例 1
01号负责人,其名下人数最多的层级是第4层(01号自身算第1层,其名下的层级逐层递增),该层有9人;因此输出[4 9]
补充说明:
如果统计09号负责人:其名下所有层级的人数都是1人,取最高层级即自身层级 1,输出[1 1]。
如果统计06号负责人:其名下第2层人数最多,有2人,输出[2 2]。
如果统计20号负责人:其名下没有层级,取自身层级 1,人数 1,输出[1 1]。
// 无节点,通过节点关键构建二叉树
// 队列遍历
class Solution {
public:
// 待实现函数,在此函数中填入答题代码;
vector<int> PointSaleSurvey(const int &total, const vector<pair<int, vector<int>>> &relations, int appointSale)
{
vector<int> result = {0, 0};
queue<pair<int, int>> Sale; //BFSQueue
map<int, int> EachLayerNum = {{1, 1}}; //存放每一层层数以及对应人数
Sale.push(make_pair(appointSale, 1));
while (!Sale.empty()) {
pair<int, int> temp = Sale.front();
Sale.pop();
int lyr = temp.second + 1; //层数++;
for (auto i : relations) {
if (i.first == temp.first) { //在relations中找到当前节点来遍历其孩子节点
int num = i.second.size();
if (!EachLayerNum.count(lyr)) { //若map中还没有这一层的key,则进行初始化
EachLayerNum[lyr] = num;
}
else {
EachLayerNum[lyr] += num; //否则进行累加
}
for (auto j : i.second) {
Sale.push(make_pair(j, lyr)); //孩子节点依次入队
}
}
}
}
for (auto i : EachLayerNum) { //找到人数最多层数
if (i.second > result[1]) {
result[0] = i.first;
result[1] = i.second;
}
}
return result;
}
};