节点定义
struct TreeNode
{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(NULL), right(NULL){};
};
递归法遍历
//前序遍历
void preorderTraversal(TreeNode* root, vector<int>& result)
{
if(root == null)
return;
result.push_back(root->val);
Traversal(root->left, result);
Traversal(root->right, result);
}
//中序遍历
void inorderTraversal(TreeNode* root, vector<int>& result)
{
if(root == null)
return;
Traversal(root->left, result);
result.push_back(root->val);
Traversal(root->right, result);
}
//后续遍历
void postorderTraversal(TreeNode* root, vector<int>& result)
{
if(root == null)
return;
Traversal(root->left, result);
Traversal(root->right, result);
result.push_back(root->val);
}
非递归(迭代)遍历
利用栈实现二叉树的三种遍历,使用一个NULL空指针做标记,来确定要弹出的数据
//前序遍历
vector<int> preorderTraversal(TreeNode* root)
{
stack<TreeNode*> st;
vector<int> result;
st.push(root);
while(!st.empty())
{
TreeNode* tmp = st.top();
if (tmp != nullptr)
{
st.pop();
if (tmp->right != nullptr) st.push(tmp->right); //右
if (tmp->left != nullptr) st.push(tmp->left); //左
st.push(tmp); //中
st.push(nullptr); //空节点做标记
}
else
{
st.pop();//空节点弹出
tmp = st.top();
st.pop();
result.push_back(tmp->val);
}
}
return result;
}
//中序遍历
vector<int> inorderTraversal(TreeNode* root)
{
stack<TreeNode*> st;
vector<int> result;
st.push(root);
while (!st.empty())
{
TreeNode* tmp = st.top();
if (tmp != nullptr)
{
st.pop();
if (tmp->right != nullptr) st.push(tmp->right); //右
st.push(tmp); //中
st.push(nullptr); //空节点做标记
if (tmp->left != nullptr) st.push(tmp->left); //左
}
else
{
st.pop();//空节点弹出
tmp = st.top();
st.pop();
result.push_back(tmp->val);
}
}
return result;
}
//后续遍历
vector<int> postorderTraversal(TreeNode* root)
{
stack<TreeNode*> st;
vector<int> result;
st.push(root);
while (!st.empty())
{
TreeNode* tmp = st.top();
if (tmp != nullptr)
{
st.pop();
st.push(tmp); //中
st.push(nullptr); //空节点做标记
if (tmp->right != nullptr) st.push(tmp->right); //右
if (tmp->left != nullptr) st.push(tmp->left); //左
}
else
{
st.pop();//空节点弹出
tmp = st.top();
st.pop();
result.push_back(tmp->val);
}
}
return result;
}
判断二叉树是否对称
//递归法
class Solution
{
public:
bool compare(TreeNode* left, TreeNode* right)
{
if(left == NULL && right == NULL) return true;
else if(left == NULL || right == NULL) return false;
else if(left->val != right->val) return false;
bool outside = compare(left->left, right->right);
bool inside = compare(left->right, right->left);
bool isSame = outside && inside;
return isSame;
}
bool isSymmetric(TreeNode* root)
{
if(root == NULL) return true;
return compare(root->left, root->right);
}
};
//迭代法
class Soultion
{
public:
bool compare(TreeNode* root)
{
queue<TreeNode*> qu;//此处使用的队列,使用栈也可以
if(root == NULL) return true;
qu.push(root->left);
qu.push(root->right);
while(!qu.empty())
{
TreeNode* left = qu.top();
qu.pop();
TreeNode* right = qu.top();
qu.pop();
if(left == NULL && right == NULL) continue;
else if(left == NULL || right == NULL) return false;
else if(left->val !== right-val) return false;
qu.push(left->left);
qu.push(right->right);
qu.push(left->right);
qu.push(right->left);
}
return true;
}
};
树的深度
//递归法
class Soultion
{
public:
int maxDepth(TreeNode* root)
{
if(root == NULL) return 0;
return 1 + max(maxDepth(root->left), maxDepth(root->right));
}
};
//迭代法
class Solution
{
public:
int maxDepth(TreeNode* root)
{
if(root == NULL) return 0;
queue<TreeNode*> qu;
int depth = 0;
qu.push(root);
while(!qu.empty())
{
int lon = qu.size();
depth++;
for(int i = 0; i < lon; i++)
{
TreeNode* tmp = qu.top();
qu.top;
if(tmp->left != NULL) qu.pus(tmp->left);
if(tmp->right != NULL) qu.pus(tmp->right);
}
]
return depth;
}
};
二叉树所有路径
//递归、回溯
class Solution
{
public:
void totalPath(TreeNode* root, vector<int>& path, vector<string>& strPath)
{
path.push_back(root->val);
if (root->left == NULL && root->right == NULL)
{
string sPath;
for (int i = 0; i < path.size() - 1; i++)
{
sPath += to_string(path[i]);
sPath += "-->";
}
sPath += to_string(path[path.size() - 1]);
strPath.push_back(sPath);
return;
}
if (root->left != NULL)
{
totalPath(root->left, path, strPath);
path.pop_back();
}
if (root->right != NULL)
{
totalPath(root->left, path, strPath);
path.pop_back();
}
}
vector<string> getTotalPath(TreeNode* root)
{
vector<int> path;
vector<string> strPath;
totalPath(root, path, strPath);
return strPath;
}
};
路径总和
//递归、回溯
class Solution {
private:
bool traversal(TreeNode* cur, int count) {
if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
if (!cur->left && !cur->right) return false; // 遇到叶子节点直接返回
if (cur->left) { // 左
count -= cur->left->val; // 递归,处理节点;
if (traversal(cur->left, count)) return true;
count += cur->left->val; // 回溯,撤销处理结果
}
if (cur->right) { // 右
count -= cur->right->val; // 递归,处理节点;
if (traversal(cur->right, count)) return true;
count += cur->right->val; // 回溯,撤销处理结果
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL) return false;
return traversal(root, sum - root->val);
}
};
//迭代
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL) return false;
// 此时栈里要放的是pair<节点指针,路径数值>
stack<pair<TreeNode*, int>> st;
st.push(pair<TreeNode*, int>(root, root->val));
while (!st.empty()) {
pair<TreeNode*, int> node = st.top();
st.pop();
// 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true
if (!node.first->left && !node.first->right && sum == node.second) return true;
// 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
if (node.first->right) {
st.push(pair<TreeNode*, int>(node.first->right, node.second + node.first->right->val));
}
// 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来
if (node.first->left) {
st.push(pair<TreeNode*, int>(node.first->left, node.second + node.first->left->val));
}
}
return false;
}
};
二叉树重建
class Solution2
{
private:
TreeNode* traversal(vector<int>& inorder, vector<int>& postorder)
{
//后序遍历的最后一个元素是根节点
if (postorder.size() == 0) return NULL;
int rootValue = postorder[postorder.size() - 1];
TreeNode* root = new TreeNode(rootValue);
if (postorder.size() == 1) return root;
int delimiterInder;
for (delimiterInder = 0; delimiterInder < postorder.size(); delimiterInder++)
{
if (inorder[delimiterInder] == rootValue)
break;
}
//中序数组,左闭右开
vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterInder);
vector<int> rightInorder(inorder.begin() + delimiterInder + 1, inorder.end());
postorder.resize(postorder.size() - 1);
//后序数组,左闭右开
vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
root->left = traversal(leftInorder, leftPostorder);
root->right = traversal(rightInorder, rightPostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
if (inorder.size() == 0 || postorder.size() == 0 || inorder.size() != postorder.size())
return NULL;
return traversal(inorder, postorder);
}
};
搜索树的最小绝对值
给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。
class Soultion11
{
private:
int result = INT_MAX;
TreeNode* pre = NULL;
vector<TreeNode*> st;
void traversal(TreeNode* cur)
{
if (cur == NULL) return;
traversal(cur->left);
if (pre != NULL)
result = min(result, cur->val - pre->val);
pre = cur;//记录前一个
traversal(cur->right);
}
public:
int getMin(TreeNode* root)
{
traversal(root);
return result;
}
};
class Soultion22
{
public:
int getMinDifference(TreeNode * root)
{
stack<TreeNode*> st;
TreeNode* cur = root;
TreeNode* pre = NULL;
int result = INT_MAX;
while (cur != NULL || !st.empty())
{
if (cur != NULL)
{
st.push(cur); //当前节点放进栈
cur = cur->left; //左
}
else
{
cur = st.top();
st.pop();
if (pre != NULL) //中
{
result = min(result, cur->val - pre->val);
}
pre = cur;
cur = cur->right; //右
}
}
return result;
}
};