zoukankan      html  css  js  c++  java
  • 【剑指offer】判断二叉树是否为平衡二叉树

    2013-09-03 14:16:51

    面试题39:求二叉树的深度、判断二叉树是否为平衡二叉树

    小结:

    1. 根据平衡二叉树的定义,需要判断每个结点,因此,需要遍历二叉树的所有结点,并判断以当前结点为根的树是否为二叉树;
    2. 用后序遍历的方式,先判断左右子树是否为平衡的,在判断当前节点;
    3. 可以对每个结点求深度,根据深度判断,如函数IsBanlancedTreeBasic所示,但这种方法存在重复遍历,效率较低;
    4. 后序遍历时,一边判断是否为平衡二叉树,一边求而二叉树的深度,这样就避免了重复遍历,如函数IsBanlancedTree所示。

    代码编写注意事项:

    1. 注意IsBanlancedTreeSub中需同时带回深度,因此在返回为true时,需要更新*pDepth的值;
    2. 写代码时,注意下面的代码由于优先级会造成错误

    if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)

    因此改为:

    1 int diff = lchilDepth - rchilDepth;
    2     if ( diff < -1 || diff > 1)
    3     {
    4         return false;
    5     }

    代码(测试通过,暂未发现问题,欢迎交流指正):

      1 #include <iostream>
      2 #include <cassert>
      3 using namespace std;
      4 
      5 typedef char DataType;
      6 const DataType LeafNode = '*';
      7 const size_t SIZE = 1000;
      8 
      9 typedef struct binaryTreeNode
     10 {
     11     DataType data;
     12     binaryTreeNode *lchild;
     13     binaryTreeNode *rchild;
     14 }BTNode,*PBTNode;
     15 
     16 //创建二叉树
     17 PBTNode CreatBiTree(PBTNode &pRoot)
     18 {
     19     DataType newData = 0;
     20 
     21     cin>>newData;
     22 
     23     if (newData == LeafNode)
     24     {
     25         return NULL;
     26     }
     27 
     28     pRoot = new BTNode;
     29     pRoot->data = newData;
     30 
     31     pRoot->lchild = CreatBiTree(pRoot->lchild);
     32     pRoot->rchild = CreatBiTree(pRoot->rchild);
     33 
     34     return pRoot;
     35 }
     36 
     37 //访问二叉树结点
     38 void VisitBiTreeNode(const PBTNode &pBTNode)
     39 {
     40     assert(NULL != pBTNode);
     41     cout<<pBTNode->data<<"	";
     42 }
     43 
     44 //前序遍历二叉树
     45 void PreOrder(const PBTNode &pRoot)
     46 {
     47     if (pRoot != NULL)
     48     {
     49         VisitBiTreeNode(pRoot);
     50         PreOrder(pRoot->lchild);
     51         PreOrder(pRoot->rchild);
     52     }
     53 }
     54 
     55 //中序遍历二叉树
     56 void InOrder(const PBTNode &pRoot)
     57 {
     58     if (pRoot != NULL)
     59     {
     60         InOrder(pRoot->lchild);
     61         VisitBiTreeNode(pRoot);
     62         InOrder(pRoot->rchild);
     63     }
     64 }
     65 
     66 //后序遍历二叉树
     67 void PostOrder(const PBTNode &pRoot)
     68 {
     69     if (pRoot != NULL)
     70     {
     71         PostOrder(pRoot->lchild);
     72         PostOrder(pRoot->rchild);
     73         VisitBiTreeNode(pRoot);
     74     }
     75 }
     76 
     77 //求二叉树深度
     78 size_t GetDepthOfBiTree(const PBTNode &pRoot)
     79 {
     80     if (NULL == pRoot)
     81     {
     82         return 0;
     83     }
     84 
     85     size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild);
     86     size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild);
     87 
     88     return ( (lchilDepth > rchilDepth) ? (lchilDepth + 1) : (rchilDepth + 1) );
     89 }
     90 
     91 
     92 //判断是否平衡二叉树,求每个结点的深度,有重复遍历
     93 bool IsBanlancedTreeBasic(const PBTNode &pRoot)
     94 {
     95     if (pRoot == NULL)   //若左子树为空,右子树的深度超过1,判断会出错
     96         return true;
     97 
     98     //return ( IsBanlancedTree(pRoot->lchild) && IsBanlancedTree(pRoot->rchild) );
     99 
    100     if ( !IsBanlancedTreeBasic(pRoot->lchild) || !IsBanlancedTreeBasic(pRoot->rchild) )
    101     {
    102         return false;
    103     }
    104 
    105     size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild);
    106     size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild);
    107     int diff = lchilDepth - rchilDepth;
    108     //if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)
    109     if ( diff < -1 || diff > 1)
    110     {
    111         return false;
    112     }
    113 
    114     return true;
    115 }
    116 
    117 //判断是否平衡二叉树,优化,没有重复遍历
    118 bool IsBanlancedTreeSub(const PBTNode &pRoot,size_t *pDepth)
    119 {
    120     if (pRoot == NULL)  
    121     {
    122         *pDepth = 0;
    123         return true;
    124     }
    125 
    126     size_t lchildDepth = 0;
    127     size_t rchildDepth = 0;
    128 
    129     if ( !IsBanlancedTreeSub(pRoot->lchild,&lchildDepth) || !IsBanlancedTreeSub(pRoot->rchild,&rchildDepth) )
    130     {
    131         return false;
    132     }
    133 
    134     int diff = lchildDepth - rchildDepth;
    135 
    136     if ( diff < -1 || diff > 1)
    137     {
    138         return false;
    139     }
    140 
    141     *pDepth = lchildDepth > rchildDepth ? (lchildDepth + 1) : (rchildDepth + 1);
    142     return true;
    143 }
    144 
    145 bool IsBanlancedTree(const PBTNode &pRoot)
    146 {
    147     size_t Depth = 0;
    148     return IsBanlancedTreeSub(pRoot,&Depth);
    149 }
    150 
    151 
    152 void DestoryBiTreeNode(PBTNode pRoot)
    153 {
    154     delete pRoot;
    155 }
    156 
    157 //销毁二叉树
    158 void DestoryBiTree(PBTNode &pRoot)
    159 {
    160     if (pRoot != NULL)
    161     {
    162         DestoryBiTree(pRoot->lchild);
    163         DestoryBiTree(pRoot->rchild);
    164         DestoryBiTreeNode(pRoot);
    165     }
    166 }
    167 
    168 //测试二叉树相关操作
    169 void TestBinaryTree()
    170 {
    171     PBTNode pRoot = NULL;
    172 
    173     cout<<"Test IsBanlancedTree..."<<endl;
    174 
    175     //测试IsBanlancedTree
    176     while (1)
    177     {
    178         cout<<"Please enter the binary tree,'*' for leaf node"<<endl;
    179         CreatBiTree(pRoot);
    180 
    181         //Test PreOrder...
    182         //cout<<"Test PreOrder..."<<endl;
    183         cout<<"The pre order is :"<<endl;
    184         PreOrder(pRoot);
    185         cout<<endl;
    186 
    187         //Test InOrder...
    188         //cout<<"Test InOrder..."<<endl;
    189         cout<<"The in order is :"<<endl;
    190         InOrder(pRoot);
    191         cout<<endl;
    192 
    193         //Test PostOrder...
    194         //cout<<"Test PostOrder..."<<endl;
    195         cout<<"The post order is :"<<endl;
    196         PostOrder(pRoot);
    197         cout<<endl;
    198 
    199         cout<<"IsBanlancedTree : "<<IsBanlancedTree(pRoot)<<endl;
    200         cout<<"IsBanlancedTreeBasic : "<<IsBanlancedTreeBasic(pRoot)<<endl;
    201 
    202         cout<<"Test DestoryBiTree..."<<endl;
    203         DestoryBiTree(pRoot);
    204     }
    205 
    206     /*cout<<"Test DestoryBiTree..."<<endl;
    207     DestoryBiTree(pRoot);*/
    208 }
    209 
    210 int main()
    211 {
    212     TestBinaryTree();
    213     return 0;
    214 }

    测试结果:

    Test IsBanlancedTree...
    Please enter the binary tree,'*' for leaf node
    ab**c**
    The pre order is :
    a       b       c
    The in order is :
    b       a       c
    The post order is :
    b       c       a
    IsBanlancedTree : 1
    IsBanlancedTreeBasic : 1
    Test DestoryBiTree...
    Please enter the binary tree,'*' for leaf node
    ab***
    The pre order is :
    a       b
    The in order is :
    b       a
    The post order is :
    b       a
    IsBanlancedTree : 1
    IsBanlancedTreeBasic : 1
    Test DestoryBiTree...
    Please enter the binary tree,'*' for leaf node
    a**
    The pre order is :
    a
    The in order is :
    a
    The post order is :
    a
    IsBanlancedTree : 1
    IsBanlancedTreeBasic : 1
    Test DestoryBiTree...
    Please enter the binary tree,'*' for leaf node
    abc****
    The pre order is :
    a       b       c
    The in order is :
    c       b       a
    The post order is :
    c       b       a
    IsBanlancedTree : 0
    IsBanlancedTreeBasic : 0
    Test DestoryBiTree...
    Please enter the binary tree,'*' for leaf node
    abcd****e*f**
    The pre order is :
    a       b       c       d       e       f
    The in order is :
    d       c       b       a       e       f
    The post order is :
    d       c       b       f       e       a
    IsBanlancedTree : 0
    IsBanlancedTreeBasic : 0
    Test DestoryBiTree...
    Please enter the binary tree,'*' for leaf node
    abd**e**cf***
    The pre order is :
    a       b       d       e       c       f
    The in order is :
    d       b       e       a       f       c
    The post order is :
    d       e       b       f       c       a
    IsBanlancedTree : 1
    IsBanlancedTreeBasic : 1
    Test DestoryBiTree...
    Please enter the binary tree,'*' for leaf node
    **
    The pre order is :
            请按任意键继续. . .
  • 相关阅读:
    Google是不是真的不能用了?非常奇怪的问题
    九度机试 题目1165:字符串匹配 2008年北京航空航天大学计算机研究生机试真题
    UNIX网络编程卷1 时间获取程序server TCP 协议相关性
    uva 1557
    C经典之14-双向链表存储1-10---ShinePans
    Java 内部类
    HiPAC高性能规则匹配算法之查找过程
    Objective-C之成魔之路【9-类构造方法和成员变量作用域、以及变量】
    NSRange,判断字符串的各种操作~
    NSRange类详解
  • 原文地址:https://www.cnblogs.com/youngforever/p/3298713.html
Copyright © 2011-2022 走看看