二叉树理论基础
二叉树的种类
- 满二叉树: 只有度为0或度为2的结点的二叉树为满二叉树。如果满二叉树的深度为 k k k,则其有 2 k − 1 2^{k}-1 2k−1个结点。
- 完全二叉树: 出最底层外其余层结点是满的,且最底层结点从左向右排列。如果完全二叉树最底层为 h h h层,则其最底层有 1 1 1~ 2 h − 1 2^{h-1} 2h−1个结点。
- 二叉搜索树: 二叉搜索树是一个有序树,如果它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;如果它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。
- 平衡二叉搜索树: 是一颗二叉搜索树,且其左右子树高度差不超过1。
二叉树的存储方式
二叉树有顺序存储和链式存储两种方式,最常用的是链式存储。
二叉树的遍历方式
二叉树有两种遍历方式:
- 深度优先遍历: 前序遍历、中序遍历、后序遍历(递归法、迭代法)
- 广度优先遍历: 层序遍历(迭代法)
二叉树递归遍历
代码
前序遍历递归代码
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> result;
Traversal(root, result);
return result;
}
private:
void Traversal(TreeNode *cur, vector<int> &result) {
if (cur == NULL)
return;
result.push_back(cur->val);
Traversal(cur->left, result);
Traversal(cur->right, result);
}
};
中序遍历递归代码
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> result;
Traversal(root, result);
return result;
}
private:
void Traversal(TreeNode *cur, vector<int> &result) {
if (cur == NULL)
return;
Traversal(cur->left, result);
result.push_back(cur->val);
Traversal(cur->right, result);
}
};
后序遍历递归代码
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> result;
Traversal(root, result);
return result;
}
private:
void Traversal(TreeNode *cur, vector<int> &result) {
if (cur == NULL)
return;
Traversal(cur->left, result);
Traversal(cur->right, result);
result.push_back(cur->val);
}
};
二叉树迭代遍历
代码
前序遍历迭代代码
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> result;
if (!root)
return result;
stack<TreeNode *> st;
st.push(root);
while (!st.empty()) {
TreeNode *cur = st.top();
st.pop();
result.push_back(cur->val);
if (cur->right)
st.push(cur->right);
if (cur->left)
st.push(cur->left);
}
return result;
}
};
中序遍历迭代代码
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode*> st;
TreeNode *cur = root;
while(cur || !st.empty())
{
if (cur){
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> postorderTraversal(TreeNode *root) {
vector<int> result;
if (!root)
return result;
stack<TreeNode *> st;
st.push(root);
while (!st.empty()) {
TreeNode *cur = st.top();
st.pop();
result.push_back(cur->val);
if (cur->left)
st.push(cur->left);
if (cur->right)
st.push(cur->right);
}
reverse(result.begin(), result.end());
return result;
}
};
二叉树统一迭代格式遍历
代码
前序遍历统一迭代格式遍历代码
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode *> st;
if (root) st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
if (node != NULL){
st.pop();
if (node->right)st.push(node->right);
if (node->left)st.push(node->left);
st.push(node);
st.push(NULL);
}
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)
st.push(root);
while (!st.empty()) {
TreeNode *node = st.top();
if (node != NULL) {
st.pop(); // 将该结点弹出,避免重复操作,下面再将右中左结点添加到栈中
if (node->right)
st.push(node->right); // 添加右结点(空结点不入栈)
st.push(node); // 添加中结点
st.push(NULL); // 中结点访问过,但是还没有处理,加入空结点作为标记
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> postorderTraversal(TreeNode *root) {
vector<int> result;
stack<TreeNode*> st;
if (root) st.push(root);
while(!st.empty()){
TreeNode* node = st.top();
if(node !=NULL){
st.pop();
st.push(node);
st.push(NULL);
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;
}
};