判断二叉树是否平衡、是否完全二叉树、是否二叉排序树

http://blog.csdn.net/zhaojinjia/article/details/11891523

来自剑指offer

求树的深度

用递归做很简单,只要知道递归出口语句的别写错。

  1. struct BinaryTreeNode  
  2. {  
  3.     int m_Value;  
  4.     BinaryTreeNode* m_pLeft;  
  5.     BinaryTreeNode* m_pRight;  
  6. };  
  7.   
  8. int TreeDepth(BinaryTreeNode* pRoot)  
  9. {  
  10.     if (pRoot == NULL)  
  11.         return 0;  
  12.   
  13.     int nLeftDepth = TreeDepth(pRoot->m_pLeft);  
  14.     int nRightDepth = TreeDepth(pRoot->m_pRight);  
  15.   
  16.     return (nLeftDepth>nRightDepth)?(nLeftDepth+1):(nRightDepth+1);  
  17. }  

判断该树是否为平衡二叉树

方法一:调用上述函数求每个节点的左右孩子深度

  1. bool IsBalanced(BinaryTreeNode* pRoot)  
  2. {  
  3.     if(pRoot== NULL)  
  4.         return true;  
  5.   
  6.     int nLeftDepth = TreeDepth(pRoot->m_pLeft);  
  7.     int nRightDepth = TreeDepth(pRoot->m_pRight);  
  8.     int diff = nRightDepth-nLeftDepth;  
  9.   
  10.     if (diff>1 || diff<-1)  
  11.         return false;  
  12.   
  13.     return IsBalanced(pRoot->m_pLeft)&&IsBalanced(pRoot->m_pRight);  
  14. }  

方法二:由于上述方法在求该结点的的左右子树深度时遍历一遍树,再次判断子树的平衡性时又遍历一遍树结构,造成遍历多次。因此方法二是一边遍历树一边判断每个结点是否具有平衡性。

  1. bool IsBalanced(BinaryTreeNode* pRoot, int* depth)  
  2. {  
  3.     if(pRoot== NULL)  
  4.     {  
  5.         *depth = 0;  
  6.         return true;  
  7.     }  
  8.   
  9.     int nLeftDepth,nRightDepth;  
  10.     bool bLeft= IsBalanced(pRoot->m_pLeft, &nLeftDepth);  
  11.     bool bRight = IsBalanced(pRoot->m_pRight, &nRightDepth);  
  12.       
  13.     if (bLeft && bRight)  
  14.     {  
  15.         int diff = nRightDepth-nLeftDepth;  
  16.         if (diff<=1 && diff>=-1)  
  17.         {  
  18.             *depth = 1+(nLeftDepth > nRightDepth ? nLeftDepth : nRightDepth);  
  19.             return true;  
  20.         }  
  21.     }  
  22.       
  23.     return false;  
  24. }  
  25.   
  26. bool IsBalanced(BinaryTreeNode* pRoot)  
  27. {  
  28.     int depth = 0;  
  29.   
  30.     return IsBalanced(pRoot, &depth);  
  31. }  
http://www.cnblogs.com/luxiaoxun/archive/2012/08/04/2622786.html

判断二叉树是否平衡、是否完全二叉树、是否二叉排序树

1.判断二叉树是否平衡

复制代码
//求树的高度
int TreeDepth(Node* t)
{
    int hl,hr,h;
    if(t != NULL)
    {
        hl = TreeDepth(t->left);
        hr = TreeDepth(t->right);
        h = hl>hr? hl:hr;
        return h+1;
    }
    return 0;
}

//判断二叉树是否平衡
int isBalanced(Node* t)  
{ 
    if(t==NULL) return 1; 
    int leftDepth = TreeDepth(t->left); 
    int rightDepth = TreeDepth(t->right); 
    if(abs(leftDepth-rightDepth) > 1) 
        return 0; 
    else 
        return isBalanced(t->left) && isBalanced(t->right); 
}
复制代码

2.判断二叉树是否相同

复制代码
//判断两棵二叉树是否相同
int CompTree(Node* tree1, Node* tree2)
{
    if(tree1 == NULL && tree2 == NULL)
        return 1;
    else if(tree1 == NULL || tree2 == NULL)
        return 0;
    if(tree1->data != tree2->data)
        return 0;
    if(CompTree(tree1->left,tree2->left)==1 && CompTree(tree1->right,tree2->right)==1)
        return 1;
    //反转二叉树也可能相同
    if(CompTree(tree1->left,tree2->right)==1 && CompTree(tree1->right,tree2->left)==1)
        return 1;
    return 0;
}
复制代码
复制代码
//拷贝二叉树   
void CopyTree(Node* s,Node* & d)  
{  
    if(s==NULL) d = NULL;  return ;
    Node* temp = new Node;  
    temp->data = s->data;  
    if(d==NULL) d = temp;  
    if(s->left) CopyTree(s->left,d->left);  
    if(s->right) CopyTree(s->right,d->right);  
} 
复制代码

3.判断二叉树是否完全二叉树

判断二叉树是否是完全二叉树:层次遍历二叉树,遍历的左右节点入队列。若出队列的结点为空,则以后出队列的结点都为空,则为完全二叉树,否则不是

复制代码
int ComplateTree(Node* bt)
{
    Node* p=bt;
    queue<Node*> q;
    int tag=0;
    if(p==NULL) return 1;
    q.push(p);
    while(!q.empty())
    {
         p=q.front(); q.pop(); 
         if(p->left && !tag) q.push(p->left);
         else if(p->left)  return 0;
         else tag=1;
         if(p->right && !tag) q.push(p->right);
         else if(p->right)  return 0;
         else tag=1;
    }
    return 1;
}
复制代码

4.判断二叉树是否二叉排序树

判断二叉树是否是二叉排序树(BST):根据中序遍历序列是否升序来判断

复制代码
bool IsBinarySortTree(Node* bt)
{
    stack<Node*> s;
    Node* p = bt;
    Node* pre = NULL;   // pre保持为p的中序前驱
    while(p || !s.empty())
    {
        if(p)
        {
            s.push(p);
            p = p->left;
        }
        else
        {
            p = s.top(); s.pop();
            if( pre && (p->data <= pre->data) )  return false;  // 不是二叉排序树
            pre = p;   // 记下前驱结点
            p = p->right;
        }
    }
    return true;  // 二叉排序树
}
复制代码

判断二叉树是否是二叉排序树(BST):层次遍历二叉树,若出队列的结点小于左结点的值,或者是大于右结点的值,则不是BST,否则是BST(感觉不对,BST要求左子树所有节点小于根节点,右子数所有节点大于跟节点,层次遍历出队只只比较左右节点而不是所有节点,应该不对!!!)

复制代码
bool IsBST(Node* T)
{
    queue<Node*> q;
    Node* p;
    if(T == NULL) return true;
    q.push(T);
    while(!q.empty())
    {
        p = q.front(); q.pop();
        if(p->left)
          if(p->data < p->left->data)
             return false;
          else q.push(p->left);
        if(p->right)
          if(p->data > p->right->data)
             return false;
          else q.push(p->right);
    }
    return true;
}
复制代码

 

作者: 阿凡卢
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值