Chinaunix首页 | 论坛 | 博客
  • 博客访问: 268796
  • 博文数量: 84
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 927
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-06 23:00
个人简介

growing

文章分类

全部博文(84)

文章存档

2017年(6)

2016年(61)

2015年(17)

我的朋友

分类: C/C++

2016-05-07 13:00:38

1.前序/中序/后序遍历/层序遍历

   见我的博客:二叉树的遍历(递归)二叉树的遍历(非递归)

2.求二叉树的高度
 
   见我的博客:二叉树的实现

3.求叶子节点的个数
 
 
  1. int _GetLeafNum(BinaryTreeNode<T>*root)
  2.     {
  3.         static int count = 0;
  4.         if(root == NULL)
  5.         {
  6.             return 0;
  7.         }
  8.         else if(root->_left == NULL&&root->_right ==NULL)
  9.         {
  10.             count++;
  11.         }
  12.         _GetLeafNum(root->_left);
  13.         _GetLeafNum(root->_right);
  14.         return count;
  15.     }


  其他思路:一个二叉树中叶子节点的个数时度为2的节点的个数减1,所以只要计算出度为二的结点有多少再减1即可(即判断一个结点的左右孩子是否为空,都不为空则+1)。

4.判断一个结点是否在二叉树中

  1. bool _Find(BinaryTreeNode<T> *root,const T& x)
  2. {
  3.     if(root == NULL)
  4.     {
  5.         return NULL;
  6.     }
  7.     else if(root->_data == x)
  8.     {
  9.         return true;
  10.     }
  11.     else
  12.     {
  13.         if(root->_left)
  14.         {
  15.             BinaryTreeNode<T> *tmp = _Find(root->_left,x);
  16.             if(tmp)
  17.                 return tmp;
  18.             else if(root->_right)
  19.             {
  20.                 return _Find(root->_right,x);
  21.             }
  22.         }
  23.     }
  24.     return false;
  25. }

5.求二叉树第k层的节点个数

  1. int _GetLevelLeafNum(const BinaryTreeNode<T> * root,const int k)
  2.     {
  3.         static int count = 0;
  4.         if(root == NULL||k < 0)
  5.         {
  6.             return 0;
  7.         }
  8.         if(k == 0)
  9.         {
  10.             count++;
  11.         }
  12.         _GetLevelLeafNum(root->_left,k-1);
  13.         _GetLevelLeafNum(root->_right,k-1);
  14.         return count;
  15.     }

6.求两个节点的最近公共祖先    LCA问题

(1)当树为查找树时
     思路:假设当前结点为cur,两个节点分别为left,right(保证right>left,如果不是就交换)。
               当cur小于ight,left时,去cur的左子树找              
               当cur大于right,left时,去cur的右子树找

               当cur在right,left中间时,即为cur              
                当right为left的父节点,为right,反过来则为left


  1. int FindLowestCommonAncestor(BinaryTreeNode<T> *cur, BinaryTreeNode<T> *u,BinaryTreeNode<T> *v)
  2. {
  3.     int left = u._data;
  4.     int right = v._data;
  5.     BinaryTreeNode<T> parent = NULL;

  6.     //保证left < right
  7.     if (left > right)
  8.     {
  9.         swap(right,left);
  10.     }

  11.     while (true)
  12.     {
  13.         if (cur->_data < left)
  14.         {
  15.             parent = cur;
  16.             cur = cur->_right;
  17.         }
  18.         else if (cur->_data > right)
  19.         {
  20.             parent = cur;
  21.             cur = cur->_left;
  22.         }
  23.         else if (cur->_data == left || cur->_data == right)
  24.         {
  25.             return parent._data;
  26.         }
  27.         else
  28.         {
  29.             return cur->_data;
  30.         }
  31.     }
  32. }
 (2)当树为普通树时
       1.有父指针时
      思路:当有父指针时,利用指针的回溯,可以得到单链表,那么问题就转换成了求两条链表相交的第一个节点。这个问题以前在我的博文《关于单链表的面试题》里分析过,请回戳^_^
      另:可以用栈来保存两个链表。
       2.没有父指针时
      
  1. BinaryTreeNode<T>* FindLowestCommonAncestor(BinaryTreeNode<T> *u,BinaryTreeNode<T> *v)
  2.     {
  3.         //flag为0两个节点都没找到,为1找了一个结点,2则找祖先成功。
  4.         int flag = 0;
  5.         BinaryTreeNode<T> *tmp = _FindAncestor(_root,u,v,flag);
  6.         if(flag == 2)
  7.         {
  8.             return tmp;
  9.         }
  10.         return NULL;
  11.     }
  12. private:
  13.     BinaryTreeNode<T>* _FindAncestor(BinaryTreeNode<T>* root,BinaryTreeNode<T>* u,BinaryTreeNode<T>* v,int &flag)
  14.     {
  15.         if(root == NULL || flag == 2)
  16.         {
  17.             return NULL;
  18.         }
  19.         BinaryTreeNode<T> *tmp = NULL;

  20.         if(root == u||root == v)
  21.         {
  22.             ++flag;
  23.             if(flag == 2)
  24.             {
  25.                 return root;
  26.             }
  27.             else
  28.             {
  29.                 tmp = root;
  30.             }
  31.         }
  32.         BinaryTreeNode<T>* left = _FindAncestor(root->_left,u,v,flag);
  33.         BinaryTreeNode<T>* right = _FindAncestor(root->_right,u,v,flag);

  34.         if(left && right)
  35.         {
  36.             return root;
  37.         }
  38.         else if(left || right)
  39.         {
  40.             tmp = left?left:right;
  41.             if(flag == 2)
  42.             {
  43.                 if(tmp == u||tmp == v)
  44.                 {
  45.                     return tmp;
  46.                 }
  47.             }
  48.         }
  49.         return tmp;
  50.     }
7.判断一棵二叉树是否是平衡二叉树
    
  1. bool _IsBalance(Node* root)
  2.     {
  3.         if(root == NULL)
  4.         {
  5.             return true;
  6.         }
  7.         int left = _Height(root->_left);
  8.         int right = _Height(root->_right);

  9.         int bf = left - right;
  10.         if(abs(bf) > 1)
  11.         {
  12.             return false;
  13.         }
  14.         if(abs(bf) != abs(root->_bf))
  15.         {
  16.             return false;
  17.         }
  18.         return _IsBalance(root->_left)&&_IsBalance(root->_right);
  19.     }
8.求二叉树中最远的两个节点的距离(二叉树中相距最远的两个节点之间的距离)

  1. void NodeMaxDistance()
  2.     {
  3.         int max = 0;
  4.         _NodeMaxDistance(_root,max);
  5.         cout<<"Distance:"<<max<<endl;
  6.     }
  7. private:
  8.     int _NodeMaxDistance(BinaryTreeNode<T> *root,int &max)
  9.     {
  10.         if(root == NULL)
  11.         {
  12.             return -1;
  13.         }
  14.         int lDistance = 1 + _NodeMaxDistance(root->_left,max);
  15.         int rDistance = 1 + _NodeMaxDistance(root->_right,max);

  16.         if (lDistance + rDistance > max)
  17.         {
  18.             max = lDistance + rDistance;
  19.         }
  20.         return lDistance > rDistance ? lDistance : rDistance;
  21.     }


9.由前序遍历,中序遍历重建二叉树

  1. void ReBuildBinaryTree(int* pPreOrder, int* pInOrder,int nodeNum)
  2.     {
  3.         _root = _ReBuildBinaryTree(pPreOrder,pInOrder,nodeNum);
  4.     }

  5. private:
  6.     BinaryTreeNode<T>* _ReBuildBinaryTree(int* pPreOrder, int* pInOrder, int nodeNum)
  7.     {
  8.         if(pPreOrder == NULL || pInOrder == NULL || nodeNum <= 0)
  9.         {
  10.             return NULL;
  11.         }
  12.         BinaryTreeNode<T> *newRoot = new BinaryTreeNode<T>;
  13.         // 前序遍历的第一个为根
  14.         newRoot ->_data = pPreOrder[0];
  15.         newRoot ->_left = NULL;
  16.         newRoot ->_right = NULL;

  17.         // 查找根节点在中序遍历中的位置,中序遍历中,根节点左边为左子树,右边为右子树
  18.         int rootPositionInOrder;
  19.         for(int i = 0; i < nodeNum; i++)
  20.         {
  21.             if(pInOrder[i] == newRoot->_data)
  22.             {
  23.                 rootPositionInOrder = i;
  24.                 break;
  25.             }
  26.         }

  27.         // 重建左子树
  28.         int nodeNumLeft = rootPositionInOrder;
  29.         int * pPreOrderLeft = pPreOrder + 1;
  30.         int * pInOrderLeft = pInOrder;
  31.         newRoot->_left = _ReBuildBinaryTree(pPreOrderLeft, pInOrderLeft, nodeNumLeft);

  32.         // 重建右子树
  33.         int nodeNumRight = nodeNum - nodeNumLeft - 1;
  34.         int * pPreOrderRight = pPreOrder + 1 + nodeNumLeft;
  35.         int * pInOrderRight = pInOrder + nodeNumLeft + 1;
  36.         newRoot->_right = _ReBuildBinaryTree(pPreOrderRight, pInOrderRight, nodeNumRight);
  37.         return newRoot;
  38.     }


10.判断一棵树是否为完全二叉树
思路:层序遍历二叉树,当一个结点的左子树为空时,右子树必须存在,且后面遍历到的结点左右子树都为空。符合此条件的树即为完全二叉树。

  1. bool IsCompleteBinaryTree()
  2.     {
  3.         return _IsCompleteBinaryTree(_root);
  4.     }
  5. private:
  6.     bool _IsCompleteBinaryTree(BinaryTreeNode<T>* root)
  7.     {
  8.         if(root == NULL)
  9.         {
  10.             return false;
  11.         }
  12.         queue<BinaryTreeNode<T>*> q;
  13.         q.push(root);
  14.         bool MustHaveNoChild = false;
  15.             
  16.         while(!q.empty())
  17.         {
  18.             BinaryTreeNode<T>* cur = q.front();
  19.             q.pop();
  20.             if(MustHaveNoChild)
  21.             {
  22.                 if(cur->_left != NULL || cur->_right != NULL)
  23.                 {
  24.                     return false;
  25.                 }
  26.             }
  27.             else
  28.             {
  29.                 if(cur->_right && cur->_left)
  30.                 {
  31.                     q.push(cur->_left);
  32.                     q.push(cur->_right);
  33.                 }
  34.                 else if(cur->_left && cur->_right == NULL)
  35.                 {
  36.                     MustHaveNoChild = true;
  37.                     q.push(cur->_left);
  38.                 }
  39.                 else if(cur->_right && cur->_left == NULL)
  40.                 {
  41.                     return false;
  42.                 }
  43.                 else
  44.                 {
  45.                     //两边都没有
  46.                     MustHaveNoChild = true;
  47.                 }
  48.             }
  49.         }
  50.         return true;
  51.     }


11.求二叉树镜像

  1. BinaryTreeNode<T>* _Mirror(BinaryTreeNode<T> *& root)
  2.     {
  3.         if(root == NULL)
  4.         {
  5.             return NULL;
  6.         }
  7.         BinaryTreeNode<T> *pLeft = _Mirror(root->_left);
  8.         BinaryTreeNode<T> *pRight = _Mirror(root->_right);

  9.         root->_left = pRight;
  10.         root->_right = pLeft;
  11.         return root;
  12.     }
12.将二叉搜索树转化为一个排序的双向链表,要求不能创建任何新的结点,只能调整树结点中指针的指向。
思路:
 
分为以下两种情况:

  1. void TransToList()
  2.     {
  3.         BinaryTreeNode<T>* FirstNode = NULL;
  4.         BinaryTreeNode<T>* LastNode = NULL;
  5.         _TranToList(_root,FirstNode,LastNode);
  6.     }
  7. private:
  8.     void _TranToList(BinaryTreeNode<T>* root,BinaryTreeNode<T>*& first,BinaryTreeNode<T>*& last)
  9.     {
  10.         if(root == NULL)
  11.         {
  12.             first = NULL;
  13.             last = NULL;
  14.             return;
  15.         }

  16.         BinaryTreeNode<T>* firstLeft = NULL,*lastLeft = NULL,*firstRight = NULL,*lastRight = NULL;
  17.         //论左
  18.         if(root->_left == NULL)
  19.         {
  20.             first = root;
  21.         }
  22.         else
  23.         {
  24.             _TranToList(root->_left,firstLeft,lastLeft);
  25.             first = firstLeft;

              //连指针

  1.             root->_left = lastLeft;
  2.             if(lastLeft)
  3.             {
  4.                 lastLeft->_right = root;
  5.             }
  6.         }
  7.         //论右
  8.         if(root->_right == NULL)
  9.         {
  10.             last = root;
  11.         }
  12.         else
  13.         {
  14.             _TranToList(root->_right,firstRight,lastRight);
  15.             last = lastRight;

  16.             //连指针
  17.             root->_right = firstRight;
  18.             if(firstRight)
  19.             {
  20.                 firstRight->_left = root;
  21.             }
  22.         }
  23.         return;
  24.     }


阅读(1708) | 评论(0) | 转发(0) |
0

上一篇:RBtree红黑树

下一篇:B-树(Btree)

给主人留下些什么吧!~~