【面试题039】二叉树的深度
题目一:
输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度。
二叉树结点的结构如下:
1
2 3 4 5 6 |
struct BinaryTreeNode
{ int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; } |
思路一:
如果一个树只有一个结点,那么这个树的深度为1,
如果根结点只有左子树而没有右子树,那么树的深度应该是其左子树的深度加1;
同样如果根结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1;
如果基友左子树又有右子树,那么该树的深度就是其左、右子树深度的最大值再加1;
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream>
#include "BinaryTree.h" using namespace std; int TreeDepth(BinaryTreeNode *pRoot) { if(pRoot == NULL) return 0; int nLeft = TreeDepth(pRoot->m_pLeft); int nRight = TreeDepth(pRoot->m_pRight); return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1); } // 1 // / // 2 3 // / // 4 5 6 // / // 7 int main() { BinaryTreeNode *pNode1 = CreateBinaryTreeNode(1); BinaryTreeNode *pNode2 = CreateBinaryTreeNode(2); BinaryTreeNode *pNode3 = CreateBinaryTreeNode(3); BinaryTreeNode *pNode4 = CreateBinaryTreeNode(4); BinaryTreeNode *pNode5 = CreateBinaryTreeNode(5); BinaryTreeNode *pNode6 = CreateBinaryTreeNode(6); BinaryTreeNode *pNode7 = CreateBinaryTreeNode(7); ConnectTreeNodes(pNode1, pNode2, pNode3); ConnectTreeNodes(pNode2, pNode4, pNode5); ConnectTreeNodes(pNode3, NULL, pNode6); ConnectTreeNodes(pNode5, pNode7, NULL); cout << TreeDepth(pNode1) << endl; DestroyTree(pNode1); return 0; } |
BinaryTree.h
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#ifndef _BINARY_TREE_H_
#define _BINARY_TREE_H_ struct BinaryTreeNode { int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; }; BinaryTreeNode *CreateBinaryTreeNode(int value); void ConnectTreeNodes(BinaryTreeNode *pParent, BinaryTreeNode *pLeft, BinaryTreeNode *pRight); void PrintTreeNode(BinaryTreeNode *pNode); void PrintTree(BinaryTreeNode *pRoot); void DestroyTree(BinaryTreeNode *pRoot); #endif //_BINARY_TREE_H_ |
BinaryTree.cpp
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include <iostream>
#include "BinaryTree.h" BinaryTreeNode *CreateBinaryTreeNode(int value) { BinaryTreeNode *pNode = new BinaryTreeNode(); pNode->m_nValue = value; pNode->m_pLeft = NULL; pNode->m_pRight = NULL; return pNode; } void ConnectTreeNodes(BinaryTreeNode *pParent, BinaryTreeNode *pLeft, BinaryTreeNode *pRight) { if(pParent != NULL) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; } } void PrintTreeNode(BinaryTreeNode *pNode) { if(pNode != NULL) { printf("value of this node is: %d ", pNode->m_nValue); if(pNode->m_pLeft != NULL) printf("value of its left child is: %d. ", pNode->m_pLeft->m_nValue); else printf("left child is null. "); if(pNode->m_pRight != NULL) printf("value of its right child is: %d. ", pNode->m_pRight->m_nValue); else printf("right child is null. "); } else { printf("this node is null. "); } printf(" "); } void PrintTree(BinaryTreeNode *pRoot) { PrintTreeNode(pRoot); if(pRoot != NULL) { if(pRoot->m_pLeft != NULL) PrintTree(pRoot->m_pLeft); if(pRoot->m_pRight != NULL) PrintTree(pRoot->m_pRight); } } void DestroyTree(BinaryTreeNode *pRoot) { if(pRoot != NULL) { BinaryTreeNode *pLeft = pRoot->m_pLeft; BinaryTreeNode *pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree(pLeft); DestroyTree(pRight); } } |
题目二:
输入一棵二叉树的根结点,判断该树是不是平衡二叉树。
如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
思路一:
根据深度来做判断,但是结点重复遍历了很多次,效率不高。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
bool IsBalanced(BinaryTreeNode *pRoot)
{ if (pRoot == NULL) { return true; } int left = TreeDepth(pRoot->m_pLeft); int right = TreeDepth(pRoot->m_pRight); int diff = left - right; if (diff > 1 || diff < -1) { return false; } return IsBalanced(pRoot->m_pLeft) && IsBalanced(pRoot->m_pRight); } |
思路二:
记住,每个结点都遍历一遍的解法才是高效的解法。
用后序遍历的方式遍历二叉树的每一个结点,在遍历到一个结点之前我们就已经遍历了它的左右子树。
只要在遍历每个结点的时候记录它的深度,我们就可以一边遍历,一边判断是不是平衡的。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
bool IsBalanced(BinaryTreeNode *pRoot, int *pDepth)
{ if (pRoot == NULL) { *pDepth = 0; return true; } int left, right; if (IsBalanced(pRoot->m_pLeft, &left) && IsBalanced(pRoot->m_pRight, &right)) { int diff = left - right; if (diff <= 1 && diff >= -1) { *pDepth = 1 + (left > right ? left : right); return true; } } return false; } bool IsBalanced(BinaryTreeNode *pRoot) { int depth = 0; return IsBalanced(pRoot, &depth); } |