常用遍历二叉树算法和LeetCode题实战汇总

目录

二叉链表存储二叉树

前序遍历

中序遍历

后序遍历

层序遍历

由遍历手段确定二叉树

小试牛刀1:LeetCode94.二叉树的中序遍历

小试牛刀2:LeetCode最大层内元素和

小试牛刀3:LeetCode100.相同的树

小试牛刀4: LeetCode144.二叉树的前序遍历


二叉链表存储二叉树

typedef struct BiTNode{
    int data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

当然表示方法有很多,大同小异,后面就直接用了

前序遍历

规则:

  • 如果二叉树为空,则返回空操作;
  • 否则先访问根结点,再前序遍历左子树,最后前序遍历右子树;

常用遍历二叉树算法和LeetCode题实战汇总_第1张图片

//前序遍历
void PreOrderTraverse(BiTree T){
    if(T==NULL)
        return;
    cout<data<lchild);//先遍历左子树
    PreOrderTraverse(T->rchild);//最后遍历右子树
}

中序遍历

规则:

  • 如果二叉树为空,则返回空操作;
  • 否则从根结点开始,先前序遍历左子树,再访问根结点,最后前序遍历右子树

 常用遍历二叉树算法和LeetCode题实战汇总_第2张图片

//中序遍历
void InOrderTraverse(BiTree T){
    if(T==NULL)
        return;
    InOrderTraverse(T->lchild);
    cout<data<rchild);
}

后序遍历

规则:

  • 如果二叉树为空,则返回空操作;
  • 否则从根结点开始,后序遍历左子树,然后后序遍历右子树,最后访问根结点

 常用遍历二叉树算法和LeetCode题实战汇总_第3张图片

//后序遍历
void PostOrderTraverse(BiTree T){
    if(T==NULL)
        return;
    PostOrderTraverse(T->lchild);
    PostOrderTraverse(T->rchild);
    cout<data<

层序遍历

规则:

  • 如果二叉为空,则返回空操作
  • 否则从树的根结点第一层开始,从上至下,从左至右进行逐层访问

层序遍历模板:

  • 创建一个 queue 队列,先将根节点( root )入队;
  • 再将 queue 队列中的元素(根节点)遍历,遍历到节点的值加入进 ret 数组,接下来看根节点,有没有左子树或右子树,如果有,则将左、右子树先后加入 temp 临时队列,最后将 queue=temp 队列,模拟 queue 中元素的出队;
  • 只要 queue 队列还不为空,则继续遍历;
  • 这时的 queue 队列中的元素则为刚才入队的左子树和右子树,并遍历按先后顺序将节点的值加入进 ret 数组;
  • 直到当 temp == nil 时,则说明没有入队元素,queue=temp,当队列为空时,整颗树就层序遍历完成了,结束循环;

 

 常用遍历二叉树算法和LeetCode题实战汇总_第4张图片

由遍历手段确定二叉树

  • 前序遍历+中序遍历可以确定二叉树
  • 后序遍历+中序遍历可以确定二叉树

前序遍历+后序遍历不能确定二叉树!!

从本质来看,四种遍历二叉树都是一种一直向前,深度优先的贪心思想

例题:前序遍历为ABCDEF,中序遍历为CBAEDF,求重建的二叉树

答案:

常用遍历二叉树算法和LeetCode题实战汇总_第5张图片

小试牛刀1:LeetCode94.二叉树的中序遍历

算是一道送福利的题,用递归很容易解决

常用遍历二叉树算法和LeetCode题实战汇总_第6张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector v;
    vector inorderTraversal(TreeNode* root) {
        InOrder(root);
        return v;
    }
    void InOrder(TreeNode* T){
        if(T==NULL)
            return;
        InOrder(T->left);
        v.push_back(T->val);
        InOrder(T->right);
    }
};

小试牛刀2:LeetCode最大层内元素和

核心:用层序遍历二叉树

给你一个二叉树的根节点 root。设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推。

请你找出层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。

 

示例:

输入:[1,7,0,7,-8,null,null]
输出:2
解释:
第 1 层各元素之和为 1,
第 2 层各元素之和为 7 + 0 = 7,
第 3 层各元素之和为 7 + -8 = -1,
所以我们返回第 2 层的层号,它的层内元素之和最大。

 

提示:

    树中的节点数介于 1 和 10^4 之间
    -10^5 <= node.val <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-level-sum-of-a-binary-tree

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxLevelSum(TreeNode* root) {
            queue q;
            if(root!=0){
                q.push(root);
            }
            int level = 0;
            int maxLevel = 1;
            int maxSum = root->val;
            while(!q.empty()){
                int size = q.size();
                int sum = 0;
                for(int i=0;ival;
                    q.pop();
                    if(cur->left!=NULL){
                        q.push(cur->left);
                    }
                    if(cur->right!=NULL){
                        q.push(cur->right);
                    }
                }
                level++;
                maxLevel = sum>maxSum?level:maxLevel;
                maxSum = sum>maxSum?sum:maxSum;
            }
    return maxLevel;
    }
};

小试牛刀3:LeetCode100.相同的树

核心:遍历二叉树,不管是用那种遍历方法均可

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:       1         1
          / \       / \
         2   3     2   3

        [1,2,3],   [1,2,3]

输出: true

示例 2:

输入:      1          1
          /           \
         2             2

        [1,2],     [1,null,2]

输出: false

示例 3:

输入:       1         1
          / \       / \
         2   1     1   2

        [1,2,1],   [1,1,2]

输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/same-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==NULL&&q==NULL)
            return true;
        if(p==NULL||q==NULL)
            return false;
        if(p->val!=q->val)
            return false;
        return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
    }
};

LeetCode实战4:144.二叉树的前序遍历

常用遍历二叉树算法和LeetCode题实战汇总_第7张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector v;
    vector preorderTraversal(TreeNode* root) {
        PreOrderTra(root);
        return v;
    }
    void PreOrderTra(TreeNode* root){
        if(root==NULL)
            return;
        v.push_back(root->val);
        PreOrderTra(root->left);
        PreOrderTra(root->right);
    }
};

还能更好吗?

用迭代代替递归解决前序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector preorderTraversal(TreeNode* root) {
        if(!root)return vector();//空树,直接返回
        stack st;
        vector ret;
        TreeNode* p=root;//p指向当前访问结点
        while(p||!st.empty())
        {
            while(p){//若当前结点非空
                ret.push_back(p->val);//访问该结点
                st.push(p);//记录该结点到栈,后面回退
                p=p->left;//进入左子树访问
            }
            // while条件的设置,保证下面st非空
            //若p非空,那么一定会压入新元素,此时st非空。若p为空,则st一定非空
            //按先序的,此时父节点已经访问,通过它拿到右孩子后就可以移除
            p=st.top();st.pop();
            p=p->right;//进入右子树访问
        }
        return ret;
    }
};

 

你可能感兴趣的:(算法—树与图论,LeetCode)