赞
踩
二叉树有满二叉树和完全二叉树两种主要的形式。
满二叉树是一种特殊的二叉树,其中每个节点要么是叶子节点(即没有子节点),要么恰好有两个子节点。
满二叉树的特性包括:
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h 从 1 开始),则该层包含 1~ 2^(h-1) 个节点。
完全二叉树的特性包括:
二叉搜索树是一个有序树,其特性为:
平衡二叉搜索树是一种特殊的二叉搜索树,常见的平衡二叉树包括 AVL(Adelson-Velsky and Landis)树和红黑树,AVL 树的性质是一棵空树或它左右两个子树的高度差绝对值不超过 1,并且左右两个子树都是一棵平衡二叉树。
C++ 中 map,set,multimap,multiset 的底层实现都是平衡二叉搜索树,所以 map 和 set 的增删操作时间复杂度是 l o g n logn logn
二叉树可以链式存储(指针),也可以顺序存储(数组)。
二叉树一般使用链式存储。
如果父节点的数组下标是 i,左孩子是 i2+1,右孩子是 i2+2
二叉树主要有两种遍历方式:
前序、中序还是后续指的是中间节点的位置:
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) :val(x), left(nullptr), right(nullptr){}
};
递归的三步分析:
https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == nullptr)return;
vec.push_back(cur->val);
traversal(cur->left, vec);
traversal(cur->right, vec);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root, result);
return result;
}
};
https://leetcode.cn/problems/binary-tree-postorder-traversal/description/
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == nullptr)return;
traversal(cur->left, vec);
traversal(cur->right, vec);
vec.push_back(cur->val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root, result);
return result;
}
};
https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
if (cur == nullptr)return;
traversal(cur->left, vec);
vec.push_back(cur->val);
traversal(cur->right, vec);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root, result);
return result;
}
};
可以用栈模拟二叉树的遍历过程。
class Solution { public: vector<int> preorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root == nullptr) return result; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != nullptr) { st.pop(); result.push_back(node->val); if(node->right) st.push(node->right); if (node->left) st.push(node->left); } } return result; } };
前序遍历的遍历顺序是“中左右”,我们可以在上面的代码的基础上稍微进行调整完成后序遍历的代码“左右中”,即先将左右的顺序调整变为“中右左”,然后在此基础上使用 reverse 函数翻转 result 数组变为“左右中”
class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root == nullptr) return result; st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != nullptr) { st.pop(); result.push_back(node->val); if (node->left) st.push(node->left); if (node->right) st.push(node->right); } } reverse(result.begin(),result.end()); return result; } };
中序遍历和前后序遍历不同,前序遍历先访问的元素是中间节点,要处理的元素也是中间节点,访问和要处理的元素是一致的,而中序节点需要一层一层向下访问,直到到达树左边的最底部,然后才开始处理节点,处理顺序和访问顺序是不一致的。
使用迭代法完成中序遍历,需要借助指针的遍历来帮助访问节点,栈用于处理节点上的元素。
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; TreeNode* cur = root; while (cur != nullptr || !st.empty()) { if (cur != nullptr) { st.push(cur); cur = cur->left; } else { cur = st.top(); st.pop(); result.push_back(cur->val); cur = cur->right; } } return result; } };
前面我们用迭代法进行前中后序遍历时的方法没有统一,下面我们使用二叉树的同意迭代法进行解决:
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root != nullptr) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != nullptr) { st.pop(); if (node->right) st.push(node->right); st.push(node); st.push(nullptr); if (node->left) st.push(node->left); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };
在此基础上我们只需要修改部分代码的位置就能实现前序遍历和后序遍历:
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root != nullptr) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != nullptr) { st.pop(); if (node->right) st.push(node->right); if (node->left) st.push(node->left); st.push(node); st.push(nullptr); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> result; stack<TreeNode*> st; if (root != nullptr) st.push(root); while (!st.empty()) { TreeNode* node = st.top(); if (node != nullptr) { st.pop(); st.push(node); st.push(nullptr); if (node->right) st.push(node->right); if (node->left) st.push(node->left); } else { st.pop(); node = st.top(); st.pop(); result.push_back(node->val); } } return result; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。