zoukankan      html  css  js  c++  java
  • 【面试题039】二叉树的深度

    【面试题039】二叉树的深度
    题目一:
        输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度。
    二叉树结点的结构如下:
    1
    2
    3
    4
    5
    6
     
    struct BinaryTreeNode
    {
        int m_nValue;
        BinaryTreeNode *m_pLeft;
        BinaryTreeNode *m_pRight;
    }
     
    思路一:
        如果一个树只有一个结点,那么这个树的深度为1,
        如果根结点只有左子树而没有右子树,那么树的深度应该是其左子树的深度加1;
        同样如果根结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1;
        如果基友左子树又有右子树,那么该树的深度就是其左、右子树深度的最大值再加1;
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    #include <iostream>
    #include "BinaryTree.h"

    using namespace std;



    int TreeDepth(BinaryTreeNode *pRoot)
    {
        if(pRoot == NULL)
            return 0;

        int nLeft = TreeDepth(pRoot->m_pLeft);
        int nRight = TreeDepth(pRoot->m_pRight);

        return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
    }
    //            1
    //         /      
    //        2        3
    //       /         
    //      4  5         6
    //        /
    //       7
    int main()
    {
        BinaryTreeNode *pNode1 = CreateBinaryTreeNode(1);
        BinaryTreeNode *pNode2 = CreateBinaryTreeNode(2);
        BinaryTreeNode *pNode3 = CreateBinaryTreeNode(3);
        BinaryTreeNode *pNode4 = CreateBinaryTreeNode(4);
        BinaryTreeNode *pNode5 = CreateBinaryTreeNode(5);
        BinaryTreeNode *pNode6 = CreateBinaryTreeNode(6);
        BinaryTreeNode *pNode7 = CreateBinaryTreeNode(7);

        ConnectTreeNodes(pNode1, pNode2, pNode3);
        ConnectTreeNodes(pNode2, pNode4, pNode5);
        ConnectTreeNodes(pNode3, NULL, pNode6);
        ConnectTreeNodes(pNode5, pNode7, NULL);

        cout << TreeDepth(pNode1) << endl;

        DestroyTree(pNode1);
        return 0;
    }
    BinaryTree.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #ifndef _BINARY_TREE_H_
    #define _BINARY_TREE_H_


    struct BinaryTreeNode
    {
        int                    m_nValue;
        BinaryTreeNode        *m_pLeft;
        BinaryTreeNode        *m_pRight;
    };

    BinaryTreeNode *CreateBinaryTreeNode(int value);
    void ConnectTreeNodes(BinaryTreeNode *pParent,
                          BinaryTreeNode *pLeft, BinaryTreeNode *pRight);
    void PrintTreeNode(BinaryTreeNode *pNode);
    void PrintTree(BinaryTreeNode *pRoot);
    void DestroyTree(BinaryTreeNode *pRoot);

    #endif //_BINARY_TREE_H_
    BinaryTree.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    #include <iostream>
    #include "BinaryTree.h"

    BinaryTreeNode *CreateBinaryTreeNode(int value)
    {
        BinaryTreeNode *pNode = new BinaryTreeNode();
        pNode->m_nValue = value;
        pNode->m_pLeft = NULL;
        pNode->m_pRight = NULL;

        return pNode;
    }

    void ConnectTreeNodes(BinaryTreeNode *pParent,
                          BinaryTreeNode *pLeft, BinaryTreeNode *pRight)
    {
        if(pParent != NULL)
        {
            pParent->m_pLeft = pLeft;
            pParent->m_pRight = pRight;
        }
    }

    void PrintTreeNode(BinaryTreeNode *pNode)
    {
        if(pNode != NULL)
        {
            printf("value of this node is: %d ", pNode->m_nValue);

            if(pNode->m_pLeft != NULL)
                printf("value of its left child is: %d. ",
                       pNode->m_pLeft->m_nValue);
            else
                printf("left child is null. ");

            if(pNode->m_pRight != NULL)
                printf("value of its right child is: %d. ",
                       pNode->m_pRight->m_nValue);
            else
                printf("right child is null. ");
        }
        else
        {
            printf("this node is null. ");
        }

        printf(" ");
    }

    void PrintTree(BinaryTreeNode *pRoot)
    {
        PrintTreeNode(pRoot);

        if(pRoot != NULL)
        {
            if(pRoot->m_pLeft != NULL)
                PrintTree(pRoot->m_pLeft);

            if(pRoot->m_pRight != NULL)
                PrintTree(pRoot->m_pRight);
        }
    }

    void DestroyTree(BinaryTreeNode *pRoot)
    {
        if(pRoot != NULL)
        {
            BinaryTreeNode *pLeft = pRoot->m_pLeft;
            BinaryTreeNode *pRight = pRoot->m_pRight;

            delete pRoot;
            pRoot = NULL;

            DestroyTree(pLeft);
            DestroyTree(pRight);
        }
    }
    题目二:
        输入一棵二叉树的根结点,判断该树是不是平衡二叉树。
    如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
     
     
    思路一:
        根据深度来做判断,但是结点重复遍历了很多次,效率不高。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    bool IsBalanced(BinaryTreeNode *pRoot)
    {
        if (pRoot == NULL)
        {
            return true;
        }
        int left = TreeDepth(pRoot->m_pLeft);
        int right = TreeDepth(pRoot->m_pRight);
        int diff = left - right;
        if (diff > 1 || diff < -1)
        {
            return false;
        }
        return IsBalanced(pRoot->m_pLeft)
               && IsBalanced(pRoot->m_pRight);
    }
     
    思路二:
        记住,每个结点都遍历一遍的解法才是高效的解法。
    用后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们就已经遍历了它的左右子树。
    只要在遍历每个结点的时候记录它的深度,我们就可以一边遍历,一边判断是不是平衡的。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    bool IsBalanced(BinaryTreeNode *pRoot, int *pDepth)
    {
        if (pRoot == NULL)
        {
            *pDepth = 0;
            return true;
        }
        int left, right;
        if (IsBalanced(pRoot->m_pLeft, &left)
                && IsBalanced(pRoot->m_pRight, &right))
        {
            int diff = left - right;
            if (diff <= 1 && diff >= -1)
            {
                *pDepth = 1 + (left > right ? left : right);
                return true;
            }
        }
        return false;
    }

    bool IsBalanced(BinaryTreeNode *pRoot)
    {
        int depth = 0;
        return IsBalanced(pRoot, &depth);
    }
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    第二章 算法基础 思考题2-4(逆序对)
    JSF中使用f:ajax标签无刷新页面改变数据
    JSF在ui:include中传递参数到对应控制层
    JSF通过超链接传递参数到控制层
    给JavaScript文件传入参数的几种方法
    Spring 与 @Resource注解
    GWT嵌入纯HTML页面
    一个分类,两个问题之ArrayList
    GWT更改元素样式属性
    Hello 2019 D 素因子贡献法计算期望 + 概率dp + 滚动数组
  • 原文地址:https://www.cnblogs.com/codemylife/p/3756447.html
Copyright © 2011-2022 走看看