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;
- }