【笔记:左程云算法与数据结构】5.二叉树

5.二叉树

    • 一、二叉树的遍历
      • 先序、中序、后序遍历
      • 宽度优先遍历(层序遍历)
      • 求二叉树的最大宽度
    • 二、二叉树的相关概念及判断
      • 搜索二叉树
      • 完全二叉树
      • 满二叉树
      • 平衡二叉树
      • 总结:树型DP
    • 三、最低公共祖先
      • 一、哈希表
      • 二、递归
    • 四、后继节点(中序遍历的后一个节点)
    • 五、二叉树的序列化和反序列化

一、二叉树的遍历

先序、中序、后序遍历

不用递归实现二叉树的先序遍历【笔记:左程云算法与数据结构】5.二叉树_第1张图片

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        //不以递归实现 栈
        vector<int> v;
        if(!root) return v;
        stack<TreeNode*> s;
        s.push(root);
        while(!s.empty())
        {
            TreeNode* cur=s.top();
            v.push_back(cur->val);
            s.pop();
            if(cur->right) s.push(cur->right);
            if(cur->left) s.push(cur->left);
        }
        return v;
    }
};

不用递归实现二叉树的后序遍历
在上面先序遍历思想的基础上,将“头左右”改为“头右左”收集
全部收集完后再进行打印。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        //栈
        if(!root) return {};
        //收集栈 这里直接用数组,后续进行反转
        vector<int> v;
        stack<TreeNode*> s;
        s.push(root);
        //头右左遍历
        while(!s.empty())
        {
            TreeNode* cur=s.top();
            s.pop();
            v.push_back(cur->val);
            if(cur->left) s.push(cur->left);
            if(cur->right) s.push(cur->right);
        }
        reverse(v.begin(),v.end());
        return v;
    }
};

不用递归实现二叉树的中序遍历
首先将树的左边界进栈,依次弹出并打印,如果有右树,则对其右树也执行如上操作

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        //非递归方法实现中序遍历
        vector<int> v;
        stack<TreeNode*> s;
        TreeNode* cur=root;
        while(!s.empty()||cur)
        {
            //当左边有孩子,进行压栈,并沿着左边界前进
            if(cur)
            {
                s.push(cur);
                cur=cur->left;
            }
            //当左边没有孩子,开始进行输出
            else{
                cur=s.top();
                s.pop();
                v.push_back(cur->val);
                cur=cur->right;
            }
        }
        return v;
    }
};

宽度优先遍历(层序遍历)

使用队列

求二叉树的最大宽度

1.哈希表
在宽度优先遍历的基础上,进栈时,用哈希表记录对应结点的层数,统计每个层数的节点数
2.用一些变量记录当前和下一层的最后一个结点

二、二叉树的相关概念及判断

搜索二叉树

概念:左树都比该节点小,右树都比该结点大
判断
1.中序遍历,为升序则为搜索二叉树

class Solution {
public:
    long maxn=LONG_MIN;
    bool isValidBST(TreeNode* root) {
        if(!root) return true;
        if(isValidBST(root->left))
        {
            if(root->val>maxn)
            {
                maxn=root->val;
                return isValidBST(root->right);
            }
        }
        return false;
    }
};

2.递归
1)左子树是搜索二叉树
2)右子树是搜索二叉树
3)左子树的最大值小于root,右子树的最大值大于root
所以构建递归函数,返回值有该子树是否为搜索二叉树,最大值与最小值(bool,int,int)

完全二叉树

判断
宽度优先遍历
1)任一节点,有右无左,返 回false
2)在1)不违规的条件下,如果遇到了第一个左右子节点不全,后续必须要都是叶节点

满二叉树

平衡二叉树

概念:左右子树的深度差不超过1
左树:1.返回是否平衡;2.返回深度(左右最大深度+1 )
右树:1.返回是否平衡;2.返回深度

总结:树型DP

左树提供信息,右树提供信息,将所需要的信息汇总在一个类中
进行递归
1)获取左树信息
2)获取右树信息
3)返回该树信息

三、最低公共祖先

一、哈希表

遍历二叉树,用哈希表存储对应节点的父节点,再从O1开始,追溯其父节点,放入集合S1中。
从O2开始,追溯其父节点,如果S1中出现了相应节点,则返回相应节点。

二、递归

如果一个节点的左子树返回值为O1,则返回O1;若一个节点的右子树返回值为O2,则返回O2. 如果该节点为O1或者O2,返回自身。其余都返回空指针
如果左右子树都不为空指针,则改节点为最低公共祖先

四、后继节点(中序遍历的后一个节点)

每个节点给出了其父节点,要求返回后继节点
1.X有右树,后继节点为右树上的最左节点
2.X无右树,找右树上的第一个左孩子

五、二叉树的序列化和反序列化

你可能感兴趣的:(左程云,算法,数据结构,leetcode)