1. 求二叉树第K层的节点个数
递归解法:
(1)如果二叉树为空或者k<1返回0(2)如果二叉树不为空并且k==1,返回1
(3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
参考代码如下:
- int GetNodeNumKthLevel(BinaryTreeNode * pRoot, int k)
- {
- if(pRoot == NULL || k < 1)
- return 0;
- if(k == 1)
- return 1;
- int numLeft = GetNodeNumKthLevel(pRoot->m_pLeft, k-1); // 左子树中k-1层的节点个数
- int numRight = GetNodeNumKthLevel(pRoot->m_pRight, k-1); // 右子树中k-1层的节点个数
- return (numLeft + numRight);
- }
2. 判断二叉树是不是平衡二叉树
递归解法:
(1)如果二叉树为空,返回真
(2)如果二叉树不为空,如果左子树和右子树都是AVL树并且左子树和右子树高度相差不大于1,返回真,其他返回假
参考代码:
- bool IsAVL(BinaryTreeNode * pRoot, int & height)
- {
- if(pRoot == NULL) // 空树,返回真
- {
- height = 0;
- return true;
- }
- int heightLeft;
- bool resultLeft = IsAVL(pRoot->m_pLeft, heightLeft);
- int heightRight;
- bool resultRight = IsAVL(pRoot->m_pRight, heightRight);
- if(resultLeft && resultRight && abs(heightLeft - heightRight) <= 1) // 左子树和右子树都是AVL,并且高度相差不大于1,返回真
- {
- height = max(heightLeft, heightRight) + 1;
- return true;
- }
- else
- {
- height = max(heightLeft, heightRight) + 1;
- return false;
- }
- }
3. 求二叉树中节点的最大距离
即二叉树中相距最远的两个节点之间的距离。
递归解法:
(1)如果二叉树为空,返回0,同时记录左子树和右子树的深度,都为0
(2)如果二叉树不为空,最大距离要么是左子树中的最大距离,要么是右子树中的最大距离,要么是左子树节点中到根节点的最大距离+右子树节点中到根节点的最大距离,同时记录左子树和右子树节点中到根节点的最大距离。
参考代码如下:
- int GetMaxDistance(BinaryTreeNode * pRoot, int & maxLeft, int & maxRight)
- {
- // maxLeft, 左子树中的节点距离根节点的最远距离
- // maxRight, 右子树中的节点距离根节点的最远距离
- if(pRoot == NULL)
- {
- maxLeft = 0;
- maxRight = 0;
- return 0;
- }
- int maxLL, maxLR, maxRL, maxRR;
- int maxDistLeft, maxDistRight;
- if(pRoot->m_pLeft != NULL)
- {
- maxDistLeft = GetMaxDistance(pRoot->m_pLeft, maxLL, maxLR);
- maxLeft = max(maxLL, maxLR) + 1;
- }
- else
- {
- maxDistLeft = 0;
- maxLeft = 0;
- }
- if(pRoot->m_pRight != NULL)
- {
- maxDistRight = GetMaxDistance(pRoot->m_pRight, maxRL, maxRR);
- maxRight = max(maxRL, maxRR) + 1;
- }
- else
- {
- maxDistRight = 0;
- maxRight = 0;
- }
- return max(max(maxDistLeft, maxDistRight), maxLeft+maxRight);
- }
4. 由前序遍历序列和中序遍历序列重建二叉树
二叉树前序遍历序列中,第一个元素总是树的根节点的值。中序遍历序列中,左子树的节点的值位于根节点的值的左边,右子树的节点的值位
于根节点的值的右边。
递归解法:
(1)如果前序遍历为空或中序遍历为空或节点个数小于等于0,返回NULL。
(2)创建根节点。前序遍历的第一个数据就是根节点的数据,在中序遍历中找到根节点的位置,可分别得知左子树和右子树的前序和中序遍
历序列,重建左右子树。
- BinaryTreeNode * RebuildBinaryTree(int* pPreOrder, int* pInOrder, int nodeNum)
- {
- if(pPreOrder == NULL || pInOrder == NULL || nodeNum <= 0)
- return NULL;
- BinaryTreeNode * pRoot = new BinaryTreeNode;
- // 前序遍历的第一个数据就是根节点数据
- pRoot->m_nValue = pPreOrder[0];
- pRoot->m_pLeft = NULL;
- pRoot->m_pRight = NULL;
- // 查找根节点在中序遍历中的位置,中序遍历中,根节点左边为左子树,右边为右子树
- int rootPositionInOrder = -1;
- for(int i = 0; i < nodeNum; i++)
- if(pInOrder[i] == pRoot->m_nValue)
- {
- rootPositionInOrder = i;
- break;
- }
- if(rootPositionInOrder == -1)
- {
- throw std::exception("Invalid input.");
- }
- // 重建左子树
- int nodeNumLeft = rootPositionInOrder;
- int * pPreOrderLeft = pPreOrder + 1;
- int * pInOrderLeft = pInOrder;
- pRoot->m_pLeft = RebuildBinaryTree(pPreOrderLeft, pInOrderLeft, nodeNumLeft);
- // 重建右子树
- int nodeNumRight = nodeNum - nodeNumLeft - 1;
- int * pPreOrderRight = pPreOrder + 1 + nodeNumLeft;
- int * pInOrderRight = pInOrder + nodeNumLeft + 1;
- pRoot->m_pRight = RebuildBinaryTree(pPreOrderRight, pInOrderRight, nodeNumRight);
- return pRoot;
- }
5.判断二叉树是不是完全二叉树
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h
层所有的结点都连续集中在最左边,这就是完全
二叉树。
有如下算法,按层次(从上到下,从左到右)遍历二叉树,当遇到一个节点的左子树为空时,则该节点右子树必须为空,且后面遍历的节点左
右子树都必须为空,否则不是完全二叉树。
- bool IsCompleteBinaryTree(BinaryTreeNode * pRoot)
- {
- if(pRoot == NULL)
- return false;
- queue<BinaryTreeNode *> q;
- q.push(pRoot);
- bool mustHaveNoChild = false;
- bool result = true;
- while(!q.empty())
- {
- BinaryTreeNode * pNode = q.front();
- q.pop();
- if(mustHaveNoChild) // 已经出现了有空子树的节点了,后面出现的必须为叶节点(左右子树都为空)
- {
- if(pNode->m_pLeft != NULL || pNode->m_pRight != NULL)
- {
- result = false;
- break;
- }
- }
- else
- {
- if(pNode->m_pLeft != NULL && pNode->m_pRight != NULL)
- {
- q.push(pNode->m_pLeft);
- q.push(pNode->m_pRight);
- }
- else if(pNode->m_pLeft != NULL && pNode->m_pRight == NULL)
- {
- mustHaveNoChild = true;
- q.push(pNode->m_pLeft);
- }
- else if(pNode->m_pLeft == NULL && pNode->m_pRight != NULL)
- {
- result = false;
- break;
- }
- else
- {
- mustHaveNoChild = true;
- }
- }
- }
- return result;
- }