数据结构-二叉树
二叉树
- C++风格二叉树节点
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
二叉树的前序遍历
前序遍历(VLR), [1] 是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。
过程:
- 访问根节点
- 前序遍历左子树
- 前序遍历右子树
复杂度:
- 假设二叉树数量为n,中序遍历时间复杂度和空间复杂度均为n
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*> stack;
vector<int> vec;
auto cur = root;
while(cur != NULL || !stack.empty()) {
while(cur != NULL) {//遍历左子树
stack.push(cur);
vec.push_back(cur->val);
cur = cur->left;
}
cur = stack.top();
stack.pop();
cur = cur->right;//前序遍历右子树
}
return vec;
}
二叉树的中序遍历
中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。
过程:
- 中序遍历左子树
- 访问根节点
- 中序遍历右子树
复杂度:
- 假设二叉树数量为n,中序遍历时间复杂度和空间复杂度均为n
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> s; //维护一个栈
vector<int> res; //存放二叉树中序遍历节点的数据
auto p = root;
while(p){ //遍历左子树,并把节点压入栈内
s.push(p);
p = p->left;
}
while(!s.empty()){
auto node = s.top();//获得栈顶值
s.pop(); //出栈
res.push_back(node->val);
p = node->right; //访问右子树
while(p){//在右子树进行中序遍历
s.push(p);
p = p->left;
}
}
return res;
}
二叉树的后序遍历
后序遍历(LRD)是二叉树遍历的一种,也叫做后根遍历、后序周游,可记做左右根。后序遍历有递归算法和非递归算法两种。在二叉树中,先左后右再根,即首先遍历左子树,然后遍历右子树,最后访问根结点。
过程:
- 后序遍历左子树
- 后序遍历右子树
- 访问根节点
复杂度:
- 假设二叉树数量为n,后序遍历时间复杂度和空间复杂度均为n
vector<int> ans;
stack<TreeNode*> s;
while(root != nullptr || !s.empty()){
if(root != nullptr){
s.push(root);
root = root->left;
}else{
TreeNode* tmp = s.top();
if(tmp->right == nullptr){
s.pop();
ans.push_back(tmp->val);
continue;
}
root = tmp->right;
tmp->right = nullptr;
}
}
return ans;
二叉树的层序遍历
除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
过程:
- 从上到下
- 从左到右
复杂度:
- 假设二叉树数量为n,层序遍历时间复杂度和空间复杂度均为n
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root) return res;
queue<TreeNode*> qu;
qu.push(root);
while(!qu.empty())
{
vector<int> tmp;
int len=qu.size();
for(int i=0;i<len;i++){
TreeNode* node=qu.front();
qu.pop();
tmp.push_back(node->val);
if(node->left) qu.push(node->left);
if(node->right) qu.push(node->right);
}
res.push_back(tmp);
}
return res;
}