(1)最基本的二叉树的 先序 中序 后序遍历
//先序遍历
void preOrder(ListNode* root)
{
if(!root) return;
cout << root->val <<endl;
preOrder(root->left);
preOrder(root->right);
}
//中序遍历
void medOrder(ListNode *root)
{
if(!root) return;
medOrder(root->left);
cout << root->val << endl;
medOrder(root->right);
}
//后序遍历
void postOrder(ListNode *root)
{
if(!root) return;
postOrder(root->left);
postOrder(root->right);
cout<< root->val << endl;
}
(2) 剑指 Offer 07. 重建二叉树
//root 表示在前序遍历中的root的位置
// left 表示 前序遍历中root节点 在中序遍历中 对应的左子树边界
//right 表示 前序遍历中root节点 在中序遍历中 对应的右子树边界
unordered_map<int, int> inorderIndex;
class Solution {
TreeNode* dfs(vector<int>& preorder, vector<int>& inorder, int root, int left, int right)
{
if(left > right) return NULL;
int rootIndexInInorder = inorderIndex[preorder[root]];
int leftTreeSize = rootIndexInInorder - left;
TreeNode* t = new TreeNode(preorder[root]);
t->left = dfs(preorder, inorder, root + 1, left, rootIndexInInorder - 1);
t->right = dfs(preorder , inorder, root + 1 + leftTreeSize,rootIndexInInorder + 1,right);
return t;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0) return NULL;
for(int i = 0; i < inorder.size(); i++)
{
inorderIndex[inorder[i]] = i;
}
TreeNode *root = dfs(preorder, inorder, 0 , 0, inorder.size() - 1);
return root;
}
};
剑指 Offer 33. 二叉搜索树的后序遍历序列
思路:利用递归 将原树分割为左子树和右子树
helper(poster, left , right) left 和 right分别表示 子树中所有节点在poster数组中 所占的索引范围
class Solution {
bool helper(vector<int> &postorder, int left, int right)
{
if(left > right) return true;
int root = postorder[right];
int med = left;//找打左子树 和 右子树的分割线
while(postorder[med] < root)
{
med++;
}
int temp = med;
while( temp < right)
{
if(postorder[temp++] < root) return false;
}
//将原树 分隔为左子树和右子树
return helper(postorder, left, med - 1)&& helper(postorder , med, right - 1);
}
public:
bool verifyPostorder(vector<int>& postorder) {
//后序遍历的顺序是 左 右 中
int size = postorder.size();
if(size == 0) return true;
return helper(postorder, 0, size - 1);
}
};
剑指 Offer 32 - I. 从上到下打印二叉树
思路:利用队列先入先出 利用辅助队列的,基本都是BFS的方法
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
if(!root) return {};
vector<int> res;
queue<TreeNode*> a;
a.push(root);
while(!a.empty())
{
TreeNode * temp = a.front();
a.pop();
res.push_back(temp->val);
if(temp->left) a.push(temp->left);
if(temp->right) a.push(temp->right);
}
return res;
}
};
剑指 Offer 32 - II. 从上到下打印二叉树 II
在上一题的基础上,利用queue.size()
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> a;
a.push(root);
while(!a.empty())
{
int len = a.size();
vector<int> temp;
while(len--)
{
TreeNode *t = a.front();
a.pop();
temp.push_back(t->val);
if(t->left) a.push(t->left);
if(t->right) a.push(t->right);
}
res.push_back(temp);
}
return res;
}
};
剑指 Offer 28. 对称的二叉树
方法一:利用递归
class Solution {
bool helper(TreeNode *left, TreeNode *right)
{
if(!left && !right) return true;
if(!left || !right || left->val != right->val) return false;
return helper(left->left, right->right) && helper(left->right, right->left);
}
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;
return helper(root->left, root->right);
}
};
方法二:非递归,利用队列 先将节点按对称的顺序存入队列中,然后 每次取两个来比较
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;
queue<TreeNode*> a;
a.push(root->left);
a.push(root->right);
while(!a.empty())
{
TreeNode *left = a.front();
a.pop();
TreeNode *right = a.front();
a.pop();
if(!left && !right) continue;
if(!left || !right || left->val!= right->val) return false;
a.push(left->left);
a.push(right->right);
a.push(left->right);
a.push(right->left);
}
return true;
}
};