代码随想录算法训练营第十天| 二叉树理论基础篇、 二叉树的递归遍历、 二叉树的迭代遍历、 二叉树的统一迭代法
写在前面
最近看上去我偷懒了,但其实还真的不是,主要是事太太太多了。中期答辩、项目问题整整做到现在,但现在挤点时间把以前的补上来吧
二叉树理论基础篇
二叉树的种类
满二叉树
什么叫满二叉树呢,就是所有的使用过的层的结点都用满就是满二叉树
完全二叉树
- 最底层可以不用填满
- 左边的节点必须填满
- 右边的可以不填
二叉搜索树
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值
- 它的左、右子树也分别为二叉排序树
平衡二叉搜索树
- 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1
- 左右两个子树都是一棵平衡二叉树。
二叉树的存储方式
链式储存
指针
顺序存储
数组
如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。
二叉树的遍历方式
深度优先遍历
先往深走,遇到叶子节点再往回走。
- 前序遍历(递归法,迭代法)
- 中序遍历(递归法,迭代法)
- 后序遍历(递归法,迭代法)
这里前中后,其实指的就是中间节点的遍历顺序
前序遍历: 中左右 5 4 1 2 6 7 8
中序遍历: 左中右 1 4 2 5 7 6 8
后序遍历: 左右中 1 2 4 7 8 6 5
广度优先遍历
一层一层的去遍历。
- 层次遍历(迭代法)
二叉树的定义
指针定义法
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
二叉树的递归遍历
前序遍历
class Solution
{
public:
void pretraversal(TreeNode *cur, vector<int> &vec)
{
if (cur == NULL)
return;
vec.push_back(cur->val); // 中
pretraversal(cur->left, vec); // 左
pretraversal(cur->right, vec); // 右
} // 前序遍历
vector<int> preorderTraversal(TreeNode *root)
{
vector<int> result;
pretraversal(root, result);
return result;
}
};
中序遍历
class Solution {
public:
void midtraversal(TreeNode *cur, vector<int> &vec)
{
if (cur == NULL)
return;
midtraversal(cur->left, vec); // 左
vec.push_back(cur->val); // 中
midtraversal(cur->right, vec); // 右
} // 中序遍历
vector<int> inorderTraversal(TreeNode *root)
{
vector<int> result;
midtraversal(root, result);
return result;
}
};
后序遍历
class Solution
{
public:
void postTraversal(TreeNode *cur, vector<int> &vec)
{
if (cur == NULL)
return;
postTraversal(cur->left, vec); // 左
postTraversal(cur->right, vec); // 右
vec.push_back(cur->val); // 中
} // 后序遍历
vector<int> postorderTraversal(TreeNode *root)
{
vector<int> result;
postTraversal(root, result);
return result;
}
};
二叉树的迭代遍历
前序遍历
class Solution
{
public:
vector<int> preorderTraversal(TreeNode *root)
{
stack<TreeNode *> st;
vector<int> result;
if (root == NULL)
return result;
st.push(root);
while (!st.empty())
{
TreeNode *node = st.top();
st.pop();
result.push_back(node->val);
if (node->right)
st.push(node->right);
if (node->left)
st.push(node->left);
}
return result;
}
};
中序遍历
class Solution
{
public:
vector<int> inorderTraversal(TreeNode *root)
{
vector<int> result;
stack<TreeNode *> st;
TreeNode *cur = root;
while (cur != NULL || !st.empty())
{
if (cur != NULL)
{
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)
{
stack<TreeNode *> st;
vector<int> result;
if (root == NULL)
return result;
st.push(root);
while (!st.empty())
{
TreeNode *node = st.top();
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;
}
};
统一迭代法
说这话,这个没看懂,周末统一看