• 二叉树常用操作


    1,前序遍历

    2,中序遍历

    3,后序遍历

    4,层序遍历

    5,二叉树的节点总数 compare 叶子节点数

    6,二叉树的深度

    7,第k层的节点个数

    8,求两个节点的最低公共祖先节点

    9,求任意两节点的距离

    10,找出二叉树中某个节点的所有祖先节点

    11,判断二叉树是否为完全二叉树


     (C++实现)

    一,前序遍历(非递归)LeetCode144

    void preOrder1(BinTree *root) //入栈时打印
    {
        stack<BinTree *> s;
        BinTree *p = root;
        while (p != NULL || !s.empty())
        {
            while (p != NULL)
            {
                cout << p->data << "";
                s.push(p);
                p = p->lchild;
            }
            if (!s.empty())
            {
                p = s.top();
                s.pop();
                p = p->rchild;
            }
        }
    }
    /*while (!s.empty() || p)
    {
        if (p)
        {
            cout << p->data;
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }
    */
    
    void preOrder2(BinTree *root) //出栈时打印
    {
        stack<BinTree *> s;
        s.push(root);
        while (!s.empty())
        {
            BinTree *cur = s.top();
            cout << cur->data << "";
            s.pop();
            s.push(cur->rchild);
            s.push(cur->lchild);
        }
    }

    二,中序遍历(非递归)LeetCode94

    void inOrder(BinTree *root) //非递归中序遍历
    {
        stack<BinTree *> s;
        BinTree *p = root;
        while (p != NULL || !s.empty())
        {
            while (p != NULL)
            {
                s.push(p);
                p = p->lchild;
            }
            if (!s.empty())
            {
                p = s.top();
                cout << p->data << "";
                s.pop();
                p = p->rchild;
            }
        }
    }

    三,后序遍历(非递归) LeetCode145   

    /* 后序遍历非递归版 */
    void PostOrderNonRec(Node * node)
    {
        if (node == nullptr)
            return;
    
        Node * pre = nullptr;
        stack<Node*> S;
        S.push(node);
    
        while (!S.empty())
        {
            node = S.top();
    
            if ((!node->left && !node->right) ||                    // 第一个输出的必是无左右子的叶子结点,只要第一个结点输出,
                (pre && (pre == node->left || pre == node->right))) // 以后的 pre 就不会是空。此处的判断语句加入一个 pre,只是用来
            {                                                       // 确保可以正确输出第一个结点。
                cout << node->data << " ";  // 左右子都全部输出,再输出当前结点
                pre = node;
                S.pop();
            }
            else
            {
                if (node->right)
                    S.push(node->right);  // 先进右子,再进左子,取出来的才是左子
                if (node->left)
                    S.push(node->left);
            }
        }
    }

     四,层序遍历 LeetCode102

    //本质上是广度优先搜索,因此会用到queue;dfs会复杂很多,详见leetcode题解

    void
    LevelOrder(Node * node) { Node * p = node; queue<Node*> Q; // 队列 Q.push(p); while (!Q.empty()) { p = Q.front(); cout << p->data << " "; Q.pop(); if (p->left) Q.push(p->left); // 注意顺序,先进左子 if (p->right) Q.push(p->right); } }

    五,二叉树的节点总数 compare 叶子节点数

    
    
    //节点总数

    int
    CountNodes(Node * node) { if (node == nullptr) return 0; return CountNodes(node->left) + CountNodes(node->right) + 1; }

    //叶子节点数
    int CountLeaves(Node * node)
    {
        if (node == nullptr)
            return 0;
      
        if (!node->left && !node->right)
            return 1;
      
        return CountLeaves(node->left) + CountLeaves(node->right);
    }

     六,二叉树的深度

    int GetDepth(Node * node)
    {
        if (node == nullptr)
            return 0;
      
        int left_depth = GetDepth(node->left);
        int right_depth = GetDepth(node->right);
      
        return left_depth > right_depth ? left_depth + 1 : right_depth + 1 ;
    }

    七,第k层的节点个数

    int GetKLevel(Node * node, int k)
    {
        if (node == nullptr)
            return 0;
      
        if (k == 1)
            return 1;
      
        return GetKLevel(node->left, k - 1) + GetKLevel(node->right, k - 1);
    }

    八,求两个节点的最低公共祖先节点 LeetCode面试题04.08

    Node * FindLCA(Node * node, Node * target1, Node * target2)
    {
        if (node == nullptr)
            return nullptr;
        if (node == target1 || node == target2)
            return node;
      
        Node * left = FindLCA(node->left, target1, target2);
        Node * right = FindLCA(node->right, target1, target2);
        if (left && right)  // 分别在左右子树
            return node;
      
        return left ? left : right;  // 都在左子树或右子树
    }

    九,求任意两节点的距离

    //先找到两节点的首个共同祖先,再计算祖先与两节点的距离之和

    //根节点与目标子节点的距离
    int
    FindLevel(Node * node, Node * target) { if (node == nullptr) return -1;  //-1代表false if (node == target) return 0;  //距离为0 int level = FindLevel(node->left, target); // 先在左子树找 if (level == -1)  //false level = FindLevel(node->right, target); // 如果左子树没找到,在右子树找 if (level != -1) // 找到了,回溯 return level + 1; return -1; // 如果左右子树都没找到 } //FindLCA为上一段代码 int DistanceNodes(Node * node, Node * target1, Node * target2) { Node * lca = FindLCA(node, target1, target2); // 找到最低公共祖先结点 int level1 = FindLevel(lca, target1); int level2 = FindLevel(lca, target2); return level1 + level2; }

    十,找出二叉树中某个节点的所有祖先节点

    bool FindAllAncestors(Node * node, Node * target)
    {
        if (node == nullptr)
            return false;
        if (node == target)
            return true;
      
        if (FindAllAncestors(node->left, target) || FindAllAncestors(node->right, target))  // 找到了
        {
            cout << node->data << " ";
            return true;  // 回溯
        }
      
        return false;  // 如果左右子树都没找到
    }

    十一,判断二叉树是否为完全二叉树

    //若某个节点只有右节点,结果为false;若某个节点只有左节点或无子节点,则改行中剩下节点无子节点,否则为false
    //flag标记变量
    bool
    IsCBT(Node * node) { bool flag = false; queue<Node*> Q; Q.push(node); while (!Q.empty()) { Node * p = Q.front(); Q.pop(); if (flag) { if (p->left || p->right) return false; } else { if (p->left && p->right) { Q.push(p->left); Q.push(p->right); } else if (p->right) // 只有右结点 return false; else if (p->left) // 只有左结点 { Q.push(p->left); flag = true; } else // 没有结点 flag = true; } } return true; }

    原文链接

  • 相关阅读:
    mysql创建表
    MySql数据类型(转)
    mysql命令总结
    php文件遍历类:FileBianli.class.php
    php文件删除
    php文件复制
    php文件遍历
    php下载c
    智能眼镜的行业应用
    《代谢增长论》读书笔记
  • 原文地址:https://www.cnblogs.com/faded828x/p/13054297.html
Copyright © 2020-2023  润新知