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 :
            请按任意键继续. . .
  • 相关阅读:
    How to Create a site at the specified URL and new database (CommandLine Operation)
    Using Wppackager to Package and Deploy Web Parts for Microsoft SharePoint Products and Technologies
    SQL Server Monitor v0.5 [Free tool]
    How to build Web Part
    Deploy web part in a virtual server by developing a Web Part Package file(.cab)
    How to recreate "sites" link if you delete it accidentally
    SharePoint Portal Server管理匿名访问设置
    Monitor sql connection from .Net SqlClient Data Provider
    Brief installation instruction of Sharepoint Portal Server
    How to Use SharePoint Alternate URL Access
  • 原文地址:https://www.cnblogs.com/youngforever/p/3298713.html
Copyright © 2011-2022 走看看