二叉树

目录:

7、【剑指Offer学习】【面试题07:重建二叉树】

8、【剑指Offer学习】【面试题08:二叉树的下一个结点】

26、【剑指Offer学习】【面试题26:树的子结构】

27、【剑指Offer学习】【面试题27:二叉树的镜像】

28、【剑指Offer学习】【面试题28:对称的二叉树】

32、【剑指Offer学习】【面试题32:不分行从上往下打印二叉树】

33、【剑指Offer学习】【面试题33:二叉搜索树的后序遍历序列】

34、【剑指Offer学习】【面试题34:二叉树中和为某一值的路径】

36、【剑指Offer学习】【面试题36:二叉搜索树与双向链表】

37、【剑指Offer学习】【面试题37:序列化二叉树】

54、【剑指Offer学习】【面试题54:二叉搜索树的第k个结点】

55、【剑指Offer学习】【面试题55:二叉树的深度】

68、【剑指Offer学习】【面试题68:树中两个结点的最低公共祖先】

7. 【剑指Offer学习】【面试题07:重建二叉树】

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.
		
		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/
		
		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================
		
		// 面试题7:重建二叉树
		// 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输
		// 入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,
		// 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},则重建出
		// 图2.6所示的二叉树并输出它的头结点。
		
		#include "..\Utilities\BinaryTree.h"
		#include <exception>
		#include <cstdio>
		
		BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder);
		
		BinaryTreeNode* Construct(int* preorder, int* inorder, int length)
		{
		    if(preorder == nullptr || inorder == nullptr || length <= 0)
		        return nullptr;
		
		    return ConstructCore(preorder, preorder + length - 1,
		        inorder, inorder + length - 1);
		}
		
		BinaryTreeNode* ConstructCore
		(
		    int* startPreorder, int* endPreorder, 
		    int* startInorder, int* endInorder
		)
		{
		    // 前序遍历序列的第一个数字是根结点的值
		    int rootValue = startPreorder[0];
		    BinaryTreeNode* root = new BinaryTreeNode();
		    root->m_nValue = rootValue;
		    root->m_pLeft = root->m_pRight = nullptr;
		
		    if(startPreorder == endPreorder)
		    {
		        if(startInorder == endInorder && *startPreorder == *startInorder)
		            return root;
		        else
		            throw std::exception("Invalid input.");
		    }
		
		    // 在中序遍历中找到根结点的值
		    int* rootInorder = startInorder;
		    while(rootInorder <= endInorder && *rootInorder != rootValue)
		        ++ rootInorder;
		
		    if(rootInorder == endInorder && *rootInorder != rootValue)
		        throw std::exception("Invalid input.");
		
		    int leftLength = rootInorder - startInorder;
		    int* leftPreorderEnd = startPreorder + leftLength;
		    if(leftLength > 0)
		    {
		        // 构建左子树
		        root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, 
		            startInorder, rootInorder - 1);
		    }
		    if(leftLength < endPreorder - startPreorder)
		    {
		        // 构建右子树
		        root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,
		            rootInorder + 1, endInorder);
		    }
		
		    return root;
		}
		
		// ====================测试代码====================
		void Test(char* testName, int* preorder, int* inorder, int length)
		{
		    if(testName != nullptr)
		        printf("%s begins:\n", testName);
		
		    printf("The preorder sequence is: ");
		    for(int i = 0; i < length; ++ i)
		        printf("%d ", preorder[i]);
		    printf("\n");
		
		    printf("The inorder sequence is: ");
		    for(int i = 0; i < length; ++ i)
		        printf("%d ", inorder[i]);
		    printf("\n");
		
		    try
		    {
		        BinaryTreeNode* root = Construct(preorder, inorder, length);
		        PrintTree(root);
		
		        DestroyTree(root);
		    }
		    catch(std::exception& exception)
		    {
		        printf("Invalid Input.\n");
		    }
		}
		
		// 普通二叉树
		//              1
		//           /     \
		//          2       3  
		//         /       / \
		//        4       5   6
		//         \         /
		//          7       8
		void Test1()
		{
		    const int length = 8;
		    int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8};
		    int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6};
		
		    Test("Test1", preorder, inorder, length);
		}
		
		// 所有结点都没有右子结点
		//            1
		//           / 
		//          2   
		//         / 
		//        3 
		//       /
		//      4
		//     /
		//    5
		void Test2()
		{
		    const int length = 5;
		    int preorder[length] = {1, 2, 3, 4, 5};
		    int inorder[length] = {5, 4, 3, 2, 1};
		
		    Test("Test2", preorder, inorder, length);
		}
		
		// 所有结点都没有左子结点
		//            1
		//             \ 
		//              2   
		//               \ 
		//                3 
		//                 \
		//                  4
		//                   \
		//                    5
		void Test3()
		{
		    const int length = 5;
		    int preorder[length] = {1, 2, 3, 4, 5};
		    int inorder[length] = {1, 2, 3, 4, 5};
		
		    Test("Test3", preorder, inorder, length);
		}
		
		// 树中只有一个结点
		void Test4()
		{
		    const int length = 1;
		    int preorder[length] = {1};
		    int inorder[length] = {1};
		
		    Test("Test4", preorder, inorder, length);
		}
		
		// 完全二叉树
		//              1
		//           /     \
		//          2       3  
		//         / \     / \
		//        4   5   6   7
		void Test5()
		{
		    const int length = 7;
		    int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
		    int inorder[length] = {4, 2, 5, 1, 6, 3, 7};
		
		    Test("Test5", preorder, inorder, length);
		}
		
		// 输入空指针
		void Test6()
		{
		    Test("Test6", nullptr, nullptr, 0);
		}
		
		// 输入的两个序列不匹配
		void Test7()
		{
		    const int length = 7;
		    int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
		    int inorder[length] = {4, 2, 8, 1, 6, 3, 7};
		
		    Test("Test7: for unmatched input", preorder, inorder, length);
		}
		
		int main(int argc, char* argv[])
		{
		    Test1();
		    Test2();
		    Test3();
		    Test4();
		    Test5();
		    Test6();
		    Test7();
		
		    return 0;
		}

8. 【剑指Offer学习】【面试题08:二叉树的下一个结点】

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.
		
		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/
		
		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================
		
		// 面试题8:二叉树的下一个结点
		// 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?
		// 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。
		
		#include <stdio.h>
		
		struct BinaryTreeNode
		{
		    int                    m_nValue;
		    BinaryTreeNode*        m_pLeft;
		    BinaryTreeNode*        m_pRight;
		    BinaryTreeNode*        m_pParent;
		};
		
		BinaryTreeNode* GetNext(BinaryTreeNode* pNode)
		{
		    if(pNode == nullptr)
		        return nullptr;
		
		    BinaryTreeNode* pNext = nullptr;
		    if(pNode->m_pRight != nullptr)
		    {
		        BinaryTreeNode* pRight = pNode->m_pRight;
		        while(pRight->m_pLeft != nullptr)
		            pRight = pRight->m_pLeft;
		
		        pNext = pRight;
		    }
		    else if(pNode->m_pParent != nullptr)
		    {
		        BinaryTreeNode* pCurrent = pNode;
		        BinaryTreeNode* pParent = pNode->m_pParent;
		        while(pParent != nullptr && pCurrent == pParent->m_pRight)
		        {
		            pCurrent = pParent;
		            pParent = pParent->m_pParent;
		        }
		
		        pNext = pParent;
		    }
		
		    return pNext;
		}
		
		// ==================== 辅助代码用来构建二叉树 ====================
		BinaryTreeNode* CreateBinaryTreeNode(int value)
		{
		    BinaryTreeNode* pNode = new BinaryTreeNode();
		    pNode->m_nValue = value;
		    pNode->m_pLeft = nullptr;
		    pNode->m_pRight = nullptr;
		    pNode->m_pParent = nullptr;
		
		    return pNode;
		}
		
		void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
		{
		    if(pParent != nullptr)
		    {
		        pParent->m_pLeft = pLeft;
		        pParent->m_pRight = pRight;
		
		        if(pLeft != nullptr)
		            pLeft->m_pParent = pParent;
		        if(pRight != nullptr)
		            pRight->m_pParent = pParent;
		    }
		}
		
		void PrintTreeNode(BinaryTreeNode* pNode)
		{
		    if(pNode != nullptr)
		    {
		        printf("value of this node is: %d\n", pNode->m_nValue);
		
		        if(pNode->m_pLeft != nullptr)
		            printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);
		        else
		            printf("left child is null.\n");
		
		        if(pNode->m_pRight != nullptr)
		            printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);
		        else
		            printf("right child is null.\n");
		    }
		    else
		    {
		        printf("this node is null.\n");
		    }
		
		    printf("\n");
		}
		
		void PrintTree(BinaryTreeNode* pRoot)
		{
		    PrintTreeNode(pRoot);
		
		    if(pRoot != nullptr)
		    {
		        if(pRoot->m_pLeft != nullptr)
		            PrintTree(pRoot->m_pLeft);
		
		        if(pRoot->m_pRight != nullptr)
		            PrintTree(pRoot->m_pRight);
		    }
		}
		
		void DestroyTree(BinaryTreeNode* pRoot)
		{
		    if(pRoot != nullptr)
		    {
		        BinaryTreeNode* pLeft = pRoot->m_pLeft;
		        BinaryTreeNode* pRight = pRoot->m_pRight;
		
		        delete pRoot;
		        pRoot = nullptr;
		
		        DestroyTree(pLeft);
		        DestroyTree(pRight);
		    }
		}
		
		// ====================测试代码====================
		void Test(char* testName, BinaryTreeNode* pNode, BinaryTreeNode* expected)
		{
		    if(testName != nullptr)
		        printf("%s begins: ", testName);
		
		    BinaryTreeNode* pNext = GetNext(pNode);
		    if(pNext == expected)
		        printf("Passed.\n");
		    else
		        printf("FAILED.\n");
		}
		
		//            8
		//        6      10
		//       5 7    9  11
		void Test1_7()
		{
		    BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
		    BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
		    BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
		    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
		    BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
		    BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
		    BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);
		
		    ConnectTreeNodes(pNode8, pNode6, pNode10);
		    ConnectTreeNodes(pNode6, pNode5, pNode7);
		    ConnectTreeNodes(pNode10, pNode9, pNode11);
		
		    Test("Test1", pNode8, pNode9);
		    Test("Test2", pNode6, pNode7);
		    Test("Test3", pNode10, pNode11);
		    Test("Test4", pNode5, pNode6);
		    Test("Test5", pNode7, pNode8);
		    Test("Test6", pNode9, pNode10);
		    Test("Test7", pNode11, nullptr);
		
		    DestroyTree(pNode8);
		}
		
		//            5
		//          4
		//        3
		//      2
		void Test8_11()
		{
		    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
		    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
		    BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
		    BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
		
		    ConnectTreeNodes(pNode5, pNode4, nullptr);
		    ConnectTreeNodes(pNode4, pNode3, nullptr);
		    ConnectTreeNodes(pNode3, pNode2, nullptr);
		
		    Test("Test8", pNode5, nullptr);
		    Test("Test9", pNode4, pNode5);
		    Test("Test10", pNode3, pNode4);
		    Test("Test11", pNode2, pNode3);
		
		    DestroyTree(pNode5);
		}
		
		//        2
		//         3
		//          4
		//           5
		void Test12_15()
		{
		    BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
		    BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
		    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
		    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
		
		    ConnectTreeNodes(pNode2, nullptr, pNode3);
		    ConnectTreeNodes(pNode3, nullptr, pNode4);
		    ConnectTreeNodes(pNode4, nullptr, pNode5);
		
		    Test("Test12", pNode5, nullptr);
		    Test("Test13", pNode4, pNode5);
		    Test("Test14", pNode3, pNode4);
		    Test("Test15", pNode2, pNode3);
		
		    DestroyTree(pNode2);
		}
		
		void Test16()
		{
		    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
		
		    Test("Test16", pNode5, nullptr);
		
		    DestroyTree(pNode5);
		}
		
		int main(int argc, char* argv[])
		{
		    Test1_7();
		    Test8_11();
		    Test12_15();
		    Test16();
		}

26. 面试题26:树的子结构

			/*******************************************************************
			Copyright(c) 2016, Harry He
			All rights reserved.

			Distributed under the BSD license.
			(See accompanying file LICENSE.txt at
			https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
			*******************************************************************/

			//==================================================================
			// 《剑指Offer——名企面试官精讲典型编程题》代码
			// 作者:何海涛
			//==================================================================

			// 面试题26:树的子结构
			// 题目:输入两棵二叉树A和B,判断B是不是A的子结构。

			#include <cstdio>

			struct BinaryTreeNode
			{
				double                 m_dbValue;
				BinaryTreeNode*        m_pLeft;
				BinaryTreeNode*        m_pRight;
			};

			bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
			bool Equal(double num1, double num2);

			bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
			{
				bool result = false;

				if(pRoot1 != nullptr && pRoot2 != nullptr)
				{
					if(Equal(pRoot1->m_dbValue, pRoot2->m_dbValue))
						result = DoesTree1HaveTree2(pRoot1, pRoot2);
					if(!result)
						result = HasSubtree(pRoot1->m_pLeft, pRoot2);
					if(!result)
						result = HasSubtree(pRoot1->m_pRight, pRoot2);
				}

				return result;
			}

			bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
			{
				if(pRoot2 == nullptr)
					return true;

				if(pRoot1 == nullptr)
					return false;

				if(!Equal(pRoot1->m_dbValue, pRoot2->m_dbValue))
					return false;

				return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
					DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
			}

			bool Equal(double num1, double num2)
			{
				if((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
					return true;
				else
					return false;
			}

			// ====================辅助测试代码====================
			BinaryTreeNode* CreateBinaryTreeNode(double dbValue)
			{
				BinaryTreeNode* pNode = new BinaryTreeNode();
				pNode->m_dbValue = dbValue;
				pNode->m_pLeft = nullptr;
				pNode->m_pRight = nullptr;

				return pNode;
			}

			void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
			{
				if(pParent != nullptr)
				{
					pParent->m_pLeft = pLeft;
					pParent->m_pRight = pRight;
				}
			}

			void DestroyTree(BinaryTreeNode* pRoot)
			{
				if(pRoot != nullptr)
				{
					BinaryTreeNode* pLeft = pRoot->m_pLeft;
					BinaryTreeNode* pRight = pRoot->m_pRight;

					delete pRoot;
					pRoot = nullptr;

					DestroyTree(pLeft);
					DestroyTree(pRight);
				}
			}

			// ====================测试代码====================
			void Test(char* testName, BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2, bool expected)
			{
				if(HasSubtree(pRoot1, pRoot2) == expected)
					printf("%s passed.\n", testName);
				else
					printf("%s failed.\n", testName);
			}

			// 树中结点含有分叉,树B是树A的子结构
			//                  8                8
			//              /       \           / \
			//             8         7         9   2
			//           /   \
			//          9     2
			//               / \
			//              4   7
			void Test1()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7);

				ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
				ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
				ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);

				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3);

				Test("Test1", pNodeA1, pNodeB1, true);

				DestroyTree(pNodeA1);
				DestroyTree(pNodeB1);
			}

			// 树中结点含有分叉,树B不是树A的子结构
			//                  8                8
			//              /       \           / \
			//             8         7         9   2
			//           /   \
			//          9     3
			//               / \
			//              4   7
			void Test2()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(7);

				ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
				ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
				ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);

				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3);

				Test("Test2", pNodeA1, pNodeB1, false);

				DestroyTree(pNodeA1);
				DestroyTree(pNodeB1);
			}

			// 树中结点只有左子结点,树B是树A的子结构
			//                8                  8
			//              /                   / 
			//             8                   9   
			//           /                    /
			//          9                    2
			//         /      
			//        2        
			//       /
			//      5
			void Test3()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNodeA1, pNodeA2, nullptr);
				ConnectTreeNodes(pNodeA2, pNodeA3, nullptr);
				ConnectTreeNodes(pNodeA3, pNodeA4, nullptr);
				ConnectTreeNodes(pNodeA4, pNodeA5, nullptr);

				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeB1, pNodeB2, nullptr);
				ConnectTreeNodes(pNodeB2, pNodeB3, nullptr);

				Test("Test3", pNodeA1, pNodeB1, true);

				DestroyTree(pNodeA1);
				DestroyTree(pNodeB1);
			}

			// 树中结点只有左子结点,树B不是树A的子结构
			//                8                  8
			//              /                   / 
			//             8                   9   
			//           /                    /
			//          9                    3
			//         /      
			//        2        
			//       /
			//      5
			void Test4()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNodeA1, pNodeA2, nullptr);
				ConnectTreeNodes(pNodeA2, pNodeA3, nullptr);
				ConnectTreeNodes(pNodeA3, pNodeA4, nullptr);
				ConnectTreeNodes(pNodeA4, pNodeA5, nullptr);

				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);

				ConnectTreeNodes(pNodeB1, pNodeB2, nullptr);
				ConnectTreeNodes(pNodeB2, pNodeB3, nullptr);

				Test("Test4", pNodeA1, pNodeB1, false);

				DestroyTree(pNodeA1);
				DestroyTree(pNodeB1);
			}

			// 树中结点只有右子结点,树B是树A的子结构
			//       8                   8
			//        \                   \ 
			//         8                   9   
			//          \                   \
			//           9                   2
			//            \      
			//             2        
			//              \
			//               5
			void Test5()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNodeA1, nullptr, pNodeA2);
				ConnectTreeNodes(pNodeA2, nullptr, pNodeA3);
				ConnectTreeNodes(pNodeA3, nullptr, pNodeA4);
				ConnectTreeNodes(pNodeA4, nullptr, pNodeA5);

				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeB1, nullptr, pNodeB2);
				ConnectTreeNodes(pNodeB2, nullptr, pNodeB3);

				Test("Test5", pNodeA1, pNodeB1, true);

				DestroyTree(pNodeA1);
				DestroyTree(pNodeB1);
			}

			// 树A中结点只有右子结点,树B不是树A的子结构
			//       8                   8
			//        \                   \ 
			//         8                   9   
			//          \                 / \
			//           9               3   2
			//            \      
			//             2        
			//              \
			//               5
			void Test6()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNodeA1, nullptr, pNodeA2);
				ConnectTreeNodes(pNodeA2, nullptr, pNodeA3);
				ConnectTreeNodes(pNodeA3, nullptr, pNodeA4);
				ConnectTreeNodes(pNodeA4, nullptr, pNodeA5);

				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeB1, nullptr, pNodeB2);
				ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4);

				Test("Test6", pNodeA1, pNodeB1, false);

				DestroyTree(pNodeA1);
				DestroyTree(pNodeB1);
			}

			// 树A为空树
			void Test7()
			{
				BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeB1, nullptr, pNodeB2);
				ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4);

				Test("Test7", nullptr, pNodeB1, false);

				DestroyTree(pNodeB1);
			}

			// 树B为空树
			void Test8()
			{
				BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNodeA1, nullptr, pNodeA2);
				ConnectTreeNodes(pNodeA2, pNodeA3, pNodeA4);

				Test("Test8", pNodeA1, nullptr, false);

				DestroyTree(pNodeA1);
			}

			// 树A和树B都为空
			void Test9()
			{
				Test("Test9", nullptr, nullptr, false);
			}

			int main(int argc, char* argv[])
			{
				Test1();
				Test2();
				Test3();
				Test4();
				Test5();
				Test6();
				Test7();
				Test8();
				Test9();

				return 0;
			}

27. 面试题27:二叉树的镜像

			/*******************************************************************
			Copyright(c) 2016, Harry He
			All rights reserved.

			Distributed under the BSD license.
			(See accompanying file LICENSE.txt at
			https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
			*******************************************************************/

			//==================================================================
			// 《剑指Offer——名企面试官精讲典型编程题》代码
			// 作者:何海涛
			//==================================================================

			// 面试题27:二叉树的镜像
			// 题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。

			#include <cstdio>
			#include "..\Utilities\BinaryTree.h"
			#include <stack>

			void MirrorRecursively(BinaryTreeNode *pNode)
			{
				if((pNode == nullptr) || (pNode->m_pLeft == nullptr && pNode->m_pRight))
					return;

				BinaryTreeNode *pTemp = pNode->m_pLeft;
				pNode->m_pLeft = pNode->m_pRight;
				pNode->m_pRight = pTemp;
				
				if(pNode->m_pLeft)
					MirrorRecursively(pNode->m_pLeft);  

				if(pNode->m_pRight)
					MirrorRecursively(pNode->m_pRight); 
			}

			void MirrorIteratively(BinaryTreeNode* pRoot)
			{
				if(pRoot == nullptr)
					return;

				std::stack<BinaryTreeNode*> stackTreeNode;
				stackTreeNode.push(pRoot);

				while(stackTreeNode.size() > 0)
				{
					BinaryTreeNode *pNode = stackTreeNode.top();
					stackTreeNode.pop();

					BinaryTreeNode *pTemp = pNode->m_pLeft;
					pNode->m_pLeft = pNode->m_pRight;
					pNode->m_pRight = pTemp;

					if(pNode->m_pLeft)
						stackTreeNode.push(pNode->m_pLeft);

					if(pNode->m_pRight)
						stackTreeNode.push(pNode->m_pRight);
				}
			}

			// ====================测试代码====================
			// 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
			//            8
			//        6      10
			//       5 7    9  11
			void Test1()
			{
				printf("=====Test1 starts:=====\n");
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

				ConnectTreeNodes(pNode8, pNode6, pNode10);
				ConnectTreeNodes(pNode6, pNode5, pNode7);
				ConnectTreeNodes(pNode10, pNode9, pNode11);

				PrintTree(pNode8);

				printf("=====Test1: MirrorRecursively=====\n");
				MirrorRecursively(pNode8);
				PrintTree(pNode8);

				printf("=====Test1: MirrorIteratively=====\n");
				MirrorIteratively(pNode8);
				PrintTree(pNode8);

				DestroyTree(pNode8);
			}

			// 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
			//            8
			//          7   
			//        6 
			//      5
			//    4
			void Test2()
			{
				printf("=====Test2 starts:=====\n");
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);

				ConnectTreeNodes(pNode8, pNode7, nullptr);
				ConnectTreeNodes(pNode7, pNode6, nullptr);
				ConnectTreeNodes(pNode6, pNode5, nullptr);
				ConnectTreeNodes(pNode5, pNode4, nullptr);

				PrintTree(pNode8);

				printf("=====Test2: MirrorRecursively=====\n");
				MirrorRecursively(pNode8);
				PrintTree(pNode8);

				printf("=====Test2: MirrorIteratively=====\n");
				MirrorIteratively(pNode8);
				PrintTree(pNode8);

				DestroyTree(pNode8);
			}

			// 测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
			//            8
			//             7   
			//              6 
			//               5
			//                4
			void Test3()
			{
				printf("=====Test3 starts:=====\n");
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);

				ConnectTreeNodes(pNode8, nullptr, pNode7);
				ConnectTreeNodes(pNode7, nullptr, pNode6);
				ConnectTreeNodes(pNode6, nullptr, pNode5);
				ConnectTreeNodes(pNode5, nullptr, pNode4);

				PrintTree(pNode8);

				printf("=====Test3: MirrorRecursively=====\n");
				MirrorRecursively(pNode8);
				PrintTree(pNode8);

				printf("=====Test3: MirrorIteratively=====\n");
				MirrorIteratively(pNode8);
				PrintTree(pNode8);

				DestroyTree(pNode8);
			}

			// 测试空二叉树:根结点为空指针
			void Test4()
			{
				printf("=====Test4 starts:=====\n");
				BinaryTreeNode* pNode = nullptr;

				PrintTree(pNode);

				printf("=====Test4: MirrorRecursively=====\n");
				MirrorRecursively(pNode);
				PrintTree(pNode);

				printf("=====Test4: MirrorIteratively=====\n");
				MirrorIteratively(pNode);
				PrintTree(pNode);
			}

			// 测试只有一个结点的二叉树
			void Test5()
			{
				printf("=====Test5 starts:=====\n");
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);

				PrintTree(pNode8);

				printf("=====Test4: MirrorRecursively=====\n");
				MirrorRecursively(pNode8);
				PrintTree(pNode8);

				printf("=====Test4: MirrorIteratively=====\n");
				MirrorIteratively(pNode8);
				PrintTree(pNode8);
			}

			int main(int argc, char* argv[])
			{
				Test1();
				Test2();
				Test3();
				Test4();
				Test5();

				return 0;
			}

28. 面试题28:对称的二叉树

			/*******************************************************************
			Copyright(c) 2016, Harry He
			All rights reserved.

			Distributed under the BSD license.
			(See accompanying file LICENSE.txt at
			https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
			*******************************************************************/

			//==================================================================
			// 《剑指Offer——名企面试官精讲典型编程题》代码
			// 作者:何海涛
			//==================================================================

			// 面试题28:对称的二叉树
			// 题目:请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和
			// 它的镜像一样,那么它是对称的。

			#include <cstdio>
			#include "../Utilities/BinaryTree.h"

			bool isSymmetrical(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);

			bool isSymmetrical(BinaryTreeNode* pRoot)
			{
				return isSymmetrical(pRoot, pRoot);
			}

			bool isSymmetrical(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
			{
				if(pRoot1 == nullptr && pRoot2 == nullptr)
					return true;

				if(pRoot1 == nullptr || pRoot2 == nullptr)
					return false;

				if(pRoot1->m_nValue != pRoot2->m_nValue)
					return false;

				return isSymmetrical(pRoot1->m_pLeft, pRoot2->m_pRight)
					&& isSymmetrical(pRoot1->m_pRight, pRoot2->m_pLeft);
			}

			// ====================测试代码====================
			void Test(char* testName, BinaryTreeNode* pRoot, bool expected)
			{
				if(testName != nullptr)
					printf("%s begins: ", testName);

				if(isSymmetrical(pRoot) == expected)
					printf("Passed.\n");
				else
					printf("FAILED.\n");
			}

			//            8
			//        6      6
			//       5 7    7 5
			void Test1()
			{
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode61 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode62 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode51 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode71 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode72 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode52 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode8, pNode61, pNode62);
				ConnectTreeNodes(pNode61, pNode51, pNode71);
				ConnectTreeNodes(pNode62, pNode72, pNode52);

				Test("Test1", pNode8, true);

				DestroyTree(pNode8);
			}

			//            8
			//        6      9
			//       5 7    7 5
			void Test2()
			{
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode61 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNode51 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode71 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode72 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode52 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode8, pNode61, pNode9);
				ConnectTreeNodes(pNode61, pNode51, pNode71);
				ConnectTreeNodes(pNode9, pNode72, pNode52);

				Test("Test2", pNode8, false);

				DestroyTree(pNode8);
			}

			//            8
			//        6      6
			//       5 7    7
			void Test3()
			{
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode61 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode62 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode51 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode71 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode72 = CreateBinaryTreeNode(7);

				ConnectTreeNodes(pNode8, pNode61, pNode62);
				ConnectTreeNodes(pNode61, pNode51, pNode71);
				ConnectTreeNodes(pNode62, pNode72, nullptr);

				Test("Test3", pNode8, false);

				DestroyTree(pNode8);
			}

			//               5
			//              / \
			//             3   3
			//            /     \
			//           4       4
			//          /         \
			//         2           2
			//        /             \
			//       1               1
			void Test4()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode31 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode32 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode41 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode42 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode21 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode22 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode11 = CreateBinaryTreeNode(1);
				BinaryTreeNode* pNode12 = CreateBinaryTreeNode(1);

				ConnectTreeNodes(pNode5, pNode31, pNode32);
				ConnectTreeNodes(pNode31, pNode41, nullptr);
				ConnectTreeNodes(pNode32, nullptr, pNode42);
				ConnectTreeNodes(pNode41, pNode21, nullptr);
				ConnectTreeNodes(pNode42, nullptr, pNode22);
				ConnectTreeNodes(pNode21, pNode11, nullptr);
				ConnectTreeNodes(pNode22, nullptr, pNode12);

				Test("Test4", pNode5, true);

				DestroyTree(pNode5);
			}


			//               5
			//              / \
			//             3   3
			//            /     \
			//           4       4
			//          /         \
			//         6           2
			//        /             \
			//       1               1
			void Test5()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode31 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode32 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode41 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode42 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode22 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode11 = CreateBinaryTreeNode(1);
				BinaryTreeNode* pNode12 = CreateBinaryTreeNode(1);

				ConnectTreeNodes(pNode5, pNode31, pNode32);
				ConnectTreeNodes(pNode31, pNode41, nullptr);
				ConnectTreeNodes(pNode32, nullptr, pNode42);
				ConnectTreeNodes(pNode41, pNode6, nullptr);
				ConnectTreeNodes(pNode42, nullptr, pNode22);
				ConnectTreeNodes(pNode6, pNode11, nullptr);
				ConnectTreeNodes(pNode22, nullptr, pNode12);

				Test("Test5", pNode5, false);

				DestroyTree(pNode5);
			}

			//               5
			//              / \
			//             3   3
			//            /     \
			//           4       4
			//          /         \
			//         2           2
			//                      \
			//                       1
			void Test6()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode31 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode32 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode41 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode42 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode21 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode22 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode12 = CreateBinaryTreeNode(1);

				ConnectTreeNodes(pNode5, pNode31, pNode32);
				ConnectTreeNodes(pNode31, pNode41, nullptr);
				ConnectTreeNodes(pNode32, nullptr, pNode42);
				ConnectTreeNodes(pNode41, pNode21, nullptr);
				ConnectTreeNodes(pNode42, nullptr, pNode22);
				ConnectTreeNodes(pNode21, nullptr, nullptr);
				ConnectTreeNodes(pNode22, nullptr, pNode12);

				Test("Test6", pNode5, false);

				DestroyTree(pNode5);
			}

			// 只有一个结点
			void Test7()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
				Test("Test7", pNode1, true);

				DestroyTree(pNode1);
			}

			// 没有结点
			void Test8()
			{
				Test("Test8", nullptr, true);
			}

			// 所有结点都有相同的值,树对称
			//               5
			//              / \
			//             5   5
			//            /     \
			//           5       5
			//          /         \
			//         5           5
			void Test9()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode21 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode22 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode31 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode32 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode41 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode42 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode1, pNode21, pNode22);
				ConnectTreeNodes(pNode21, pNode31, nullptr);
				ConnectTreeNodes(pNode22, nullptr, pNode32);
				ConnectTreeNodes(pNode31, pNode41, nullptr);
				ConnectTreeNodes(pNode32, nullptr, pNode42);
				ConnectTreeNodes(pNode41, nullptr, nullptr);
				ConnectTreeNodes(pNode42, nullptr, nullptr);

				Test("Test9", pNode1, true);

				DestroyTree(pNode1);
			}

			// 所有结点都有相同的值,树不对称
			//               5
			//              / \
			//             5   5
			//            /     \
			//           5       5
			//          /       /
			//         5       5
			void Test10()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode21 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode22 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode31 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode32 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode41 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode42 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode1, pNode21, pNode22);
				ConnectTreeNodes(pNode21, pNode31, nullptr);
				ConnectTreeNodes(pNode22, nullptr, pNode32);
				ConnectTreeNodes(pNode31, pNode41, nullptr);
				ConnectTreeNodes(pNode32, pNode42, nullptr);
				ConnectTreeNodes(pNode41, nullptr, nullptr);
				ConnectTreeNodes(pNode42, nullptr, nullptr);

				Test("Test10", pNode1, false);

				DestroyTree(pNode1);
			}

			void main(int argc, char* argv[])
			{
				Test1();
				Test2();
				Test3();
				Test4();
				Test5();
				Test6();
				Test7();
				Test8();
				Test9();
				Test10();
			}


		}

32. 面试题32:不分行从上往下打印二叉树

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题32(一):不分行从上往下打印二叉树
		// 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。

		#include <cstdio>
		#include "..\Utilities\BinaryTree.h"
		#include <deque>

		void PrintFromTopToBottom(BinaryTreeNode* pRoot)
		{
			if(pRoot == nullptr)
				return;

			std::deque<BinaryTreeNode *> dequeTreeNode;

			dequeTreeNode.push_back(pRoot);

			while(dequeTreeNode.size())
			{
				BinaryTreeNode *pNode = dequeTreeNode.front();
				dequeTreeNode.pop_front();

				printf("%d ", pNode->m_nValue);

				if(pNode->m_pLeft)
					dequeTreeNode.push_back(pNode->m_pLeft);

				if(pNode->m_pRight)
					dequeTreeNode.push_back(pNode->m_pRight);
			}
		}

		// ====================测试代码====================
		void Test(char* testName, BinaryTreeNode* pRoot)
		{
			if(testName != nullptr)
				printf("%s begins: \n", testName);

			PrintTree(pRoot);

			printf("The nodes from top to bottom, from left to right are: \n");
			PrintFromTopToBottom(pRoot);

			printf("\n\n");
		}

		//            10
		//         /      \
		//        6        14
		//       /\        /\
		//      4  8     12  16
		void Test1()
		{
			BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
			BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
			BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
			BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
			BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);

			ConnectTreeNodes(pNode10, pNode6, pNode14);
			ConnectTreeNodes(pNode6, pNode4, pNode8);
			ConnectTreeNodes(pNode14, pNode12, pNode16);

			Test("Test1", pNode10);

			DestroyTree(pNode10);
		}

		//               5
		//              /
		//             4
		//            /
		//           3
		//          /
		//         2
		//        /
		//       1
		void Test2()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

			ConnectTreeNodes(pNode5, pNode4, nullptr);
			ConnectTreeNodes(pNode4, pNode3, nullptr);
			ConnectTreeNodes(pNode3, pNode2, nullptr);
			ConnectTreeNodes(pNode2, pNode1, nullptr);

			Test("Test2", pNode5);

			DestroyTree(pNode5);
		}

		// 1
		//  \
		//   2
		//    \
		//     3
		//      \
		//       4
		//        \
		//         5
		void Test3()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			ConnectTreeNodes(pNode1, nullptr, pNode2);
			ConnectTreeNodes(pNode2, nullptr, pNode3);
			ConnectTreeNodes(pNode3, nullptr, pNode4);
			ConnectTreeNodes(pNode4, nullptr, pNode5);

			Test("Test3", pNode1);

			DestroyTree(pNode1);
		}

		// 树中只有1个结点
		void Test4()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			Test("Test4", pNode1);

			DestroyTree(pNode1);
		}

		// 树中没有结点
		void Test5()
		{
			Test("Test5", nullptr);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();

		   return 0;
		}

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题32(二):分行从上到下打印二叉树
		// 题目:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层
		// 打印到一行。

		#include <cstdio>
		#include "..\Utilities\BinaryTree.h"
		#include <queue>

		void Print(BinaryTreeNode* pRoot)
		{
			if(pRoot == nullptr)
				return;

			std::queue<BinaryTreeNode*> nodes;
			nodes.push(pRoot);
			int nextLevel = 0;
			int toBePrinted = 1;
			while(!nodes.empty())
			{
				BinaryTreeNode* pNode = nodes.front();
				printf("%d ", pNode->m_nValue);

				if(pNode->m_pLeft != nullptr)
				{
					nodes.push(pNode->m_pLeft);
					++nextLevel;
				}
				if(pNode->m_pRight != nullptr)
				{
					nodes.push(pNode->m_pRight);
					++nextLevel;
				}

				nodes.pop();
				--toBePrinted;
				if(toBePrinted == 0)
				{
					printf("\n");
					toBePrinted = nextLevel;
					nextLevel = 0;
				}
			}
		}

		// ====================测试代码====================
		//            8
		//        6      10
		//       5 7    9  11
		void Test1()
		{
			BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
			BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
			BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
			BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
			BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

			ConnectTreeNodes(pNode8, pNode6, pNode10);
			ConnectTreeNodes(pNode6, pNode5, pNode7);
			ConnectTreeNodes(pNode10, pNode9, pNode11);

			printf("====Test1 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("8 \n");
			printf("6 10 \n");
			printf("5 7 9 11 \n\n");

			printf("Actual Result is: \n");
			Print(pNode8);
			printf("\n");

			DestroyTree(pNode8);
		}

		//            5
		//          4
		//        3
		//      2
		void Test2()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);

			ConnectTreeNodes(pNode5, pNode4, nullptr);
			ConnectTreeNodes(pNode4, pNode3, nullptr);
			ConnectTreeNodes(pNode3, pNode2, nullptr);

			printf("====Test2 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("5 \n");
			printf("4 \n");
			printf("3 \n");
			printf("2 \n\n");

			printf("Actual Result is: \n");
			Print(pNode5);
			printf("\n");

			DestroyTree(pNode5);
		}

		//        5
		//         4
		//          3
		//           2
		void Test3()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);

			ConnectTreeNodes(pNode5, nullptr, pNode4);
			ConnectTreeNodes(pNode4, nullptr, pNode3);
			ConnectTreeNodes(pNode3, nullptr, pNode2);

			printf("====Test3 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("5 \n");
			printf("4 \n");
			printf("3 \n");
			printf("2 \n\n");

			printf("Actual Result is: \n");
			Print(pNode5);
			printf("\n");

			DestroyTree(pNode5);
		}

		void Test4()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			printf("====Test4 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("5 \n\n");

			printf("Actual Result is: \n");
			Print(pNode5);
			printf("\n");

			DestroyTree(pNode5);
		}

		void Test5()
		{
			printf("====Test5 Begins: ====\n");
			printf("Expected Result is:\n");

			printf("Actual Result is: \n");
			Print(nullptr);
			printf("\n");
		}

		//        100
		//        /
		//       50   
		//         \
		//         150
		void Test6()
		{
			BinaryTreeNode* pNode100 = CreateBinaryTreeNode(100);
			BinaryTreeNode* pNode50 = CreateBinaryTreeNode(50);
			BinaryTreeNode* pNode150 = CreateBinaryTreeNode(150);

			ConnectTreeNodes(pNode100, pNode50, nullptr);
			ConnectTreeNodes(pNode50, nullptr, pNode150);

			printf("====Test6 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("100 \n");
			printf("50 \n");
			printf("150 \n\n");

			printf("Actual Result is: \n");
			Print(pNode100);
			printf("\n");
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();
			Test6();

			return 0;
		}

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题32(三):之字形打印二叉树
		// 题目:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺
		// 序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,
		// 其他行以此类推。

		#include <cstdio>
		#include "..\Utilities\BinaryTree.h"
		#include <stack>

		void Print(BinaryTreeNode* pRoot)
		{
			if(pRoot == nullptr)
				return;

			std::stack<BinaryTreeNode*> levels[2];
			int current = 0;
			int next = 1;

			levels[current].push(pRoot);
			while(!levels[0].empty() || !levels[1].empty())
			{
				BinaryTreeNode* pNode = levels[current].top();
				levels[current].pop();

				printf("%d ", pNode->m_nValue);

				if(current == 0)
				{
					if(pNode->m_pLeft != nullptr)
						levels[next].push(pNode->m_pLeft);
					if(pNode->m_pRight != nullptr)
						levels[next].push(pNode->m_pRight);
				}
				else
				{
					if(pNode->m_pRight != nullptr)
						levels[next].push(pNode->m_pRight);
					if(pNode->m_pLeft != nullptr)
						levels[next].push(pNode->m_pLeft);
				}

				if(levels[current].empty())
				{
					printf("\n");
					current = 1 - current;
					next = 1 - next;
				}
			}
		}

		// ====================测试代码====================
		//            8
		//        6      10
		//       5 7    9  11
		void Test1()
		{
			BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
			BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
			BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
			BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
			BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

			ConnectTreeNodes(pNode8, pNode6, pNode10);
			ConnectTreeNodes(pNode6, pNode5, pNode7);
			ConnectTreeNodes(pNode10, pNode9, pNode11);

			printf("====Test1 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("8 \n");
			printf("10 6 \n");
			printf("5 7 9 11 \n\n");

			printf("Actual Result is: \n");
			Print(pNode8);
			printf("\n");

			DestroyTree(pNode8);
		}

		//            5
		//          4
		//        3
		//      2
		void Test2()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);

			ConnectTreeNodes(pNode5, pNode4, nullptr);
			ConnectTreeNodes(pNode4, pNode3, nullptr);
			ConnectTreeNodes(pNode3, pNode2, nullptr);

			printf("====Test2 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("5 \n");
			printf("4 \n");
			printf("3 \n");
			printf("2 \n\n");

			printf("Actual Result is: \n");
			Print(pNode5);
			printf("\n");

			DestroyTree(pNode5);
		}

		//        5
		//         4
		//          3
		//           2
		void Test3()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);

			ConnectTreeNodes(pNode5, nullptr, pNode4);
			ConnectTreeNodes(pNode4, nullptr, pNode3);
			ConnectTreeNodes(pNode3, nullptr, pNode2);

			printf("====Test3 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("5 \n");
			printf("4 \n");
			printf("3 \n");
			printf("2 \n\n");

			printf("Actual Result is: \n");
			Print(pNode5);
			printf("\n");

			DestroyTree(pNode5);
		}

		void Test4()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			printf("====Test4 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("5 \n\n");

			printf("Actual Result is: \n");
			Print(pNode5);
			printf("\n");

			DestroyTree(pNode5);
		}

		void Test5()
		{
			printf("====Test5 Begins: ====\n");
			printf("Expected Result is:\n");

			printf("Actual Result is: \n");
			Print(nullptr);
			printf("\n");
		}

		//        100
		//        /
		//       50   
		//         \
		//         150
		void Test6()
		{
			BinaryTreeNode* pNode100 = CreateBinaryTreeNode(100);
			BinaryTreeNode* pNode50 = CreateBinaryTreeNode(50);
			BinaryTreeNode* pNode150 = CreateBinaryTreeNode(150);

			ConnectTreeNodes(pNode100, pNode50, nullptr);
			ConnectTreeNodes(pNode50, nullptr, pNode150);

			printf("====Test6 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("100 \n");
			printf("50 \n");
			printf("150 \n\n");

			printf("Actual Result is: \n");
			Print(pNode100);
			printf("\n");
		}

		//                8
		//        4              12
		//     2     6       10      14
		//   1  3  5  7     9 11   13  15
		void Test7()
		{
			BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
			BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
			BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
			BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
			BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);
			BinaryTreeNode* pNode13 = CreateBinaryTreeNode(13);
			BinaryTreeNode* pNode15 = CreateBinaryTreeNode(15);

			ConnectTreeNodes(pNode8, pNode4, pNode12);
			ConnectTreeNodes(pNode4, pNode2, pNode6);
			ConnectTreeNodes(pNode12, pNode10, pNode14);
			ConnectTreeNodes(pNode2, pNode1, pNode3);
			ConnectTreeNodes(pNode6, pNode5, pNode7);
			ConnectTreeNodes(pNode10, pNode9, pNode11);
			ConnectTreeNodes(pNode14, pNode13, pNode15);

			printf("====Test7 Begins: ====\n");
			printf("Expected Result is:\n");
			printf("8 \n");
			printf("12 4 \n");
			printf("2 6 10 14 \n");
			printf("15 13 11 9 7 5 3 1 \n\n");

			printf("Actual Result is: \n");
			Print(pNode8);
			printf("\n");

			DestroyTree(pNode8);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();
			Test6();
			Test7();

			return 0;
		}

33. 面试题33:二叉搜索树的后序遍历序列

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题33:二叉搜索树的后序遍历序列
		// 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
		// 如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。

		#include <cstdio>

		// BST:Binary Search Tree,二叉搜索树
		bool VerifySquenceOfBST(int sequence[], int length)
		{
			if(sequence == nullptr || length <= 0)
				return false;

			int root = sequence[length - 1];

			// 在二叉搜索树中左子树的结点小于根结点
			int i = 0;
			for(; i < length - 1; ++ i)
			{
				if(sequence[i] > root)
					break;
			}

			// 在二叉搜索树中右子树的结点大于根结点
			int j = i;
			for(; j < length - 1; ++ j)
			{
				if(sequence[j] < root)
					return false;
			}

			// 判断左子树是不是二叉搜索树
			bool left = true;
			if(i > 0)
				left = VerifySquenceOfBST(sequence, i);

			// 判断右子树是不是二叉搜索树
			bool right = true;
			if(i < length - 1)
				right = VerifySquenceOfBST(sequence + i, length - i - 1);

			return (left && right);
		}

		// ====================测试代码====================
		void Test(const char* testName, int sequence[], int length, bool expected)
		{
			if(testName != nullptr)
				printf("%s begins: ", testName);

			if(VerifySquenceOfBST(sequence, length) == expected)
				printf("passed.\n");
			else
				printf("failed.\n");
		}

		//            10
		//         /      \
		//        6        14
		//       /\        /\
		//      4  8     12  16
		void Test1()
		{
			int data[] = {4, 8, 6, 12, 16, 14, 10};
			Test("Test1", data, sizeof(data)/sizeof(int), true);
		}

		//           5
		//          / \
		//         4   7
		//            /
		//           6
		void Test2()
		{
			int data[] = {4, 6, 7, 5};
			Test("Test2", data, sizeof(data)/sizeof(int), true);
		}

		//               5
		//              /
		//             4
		//            /
		//           3
		//          /
		//         2
		//        /
		//       1
		void Test3()
		{
			int data[] = {1, 2, 3, 4, 5};
			Test("Test3", data, sizeof(data)/sizeof(int), true);
		}

		// 1
		//  \
		//   2
		//    \
		//     3
		//      \
		//       4
		//        \
		//         5
		void Test4()
		{
			int data[] = {5, 4, 3, 2, 1};
			Test("Test4", data, sizeof(data)/sizeof(int), true);
		}

		// 树中只有1个结点
		void Test5()
		{
			int data[] = {5};
			Test("Test5", data, sizeof(data)/sizeof(int), true);
		}

		void Test6()
		{
			int data[] = {7, 4, 6, 5};
			Test("Test6", data, sizeof(data)/sizeof(int), false);
		}

		void Test7()
		{
			int data[] = {4, 6, 12, 8, 16, 14, 10};
			Test("Test7", data, sizeof(data)/sizeof(int), false);
		}

		void Test8()
		{
			Test("Test8", nullptr, 0, false);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();
			Test6();
			Test7();
			Test8();

			return 0;
		}

34. 面试题34:二叉树中和为某一值的路径

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题34:二叉树中和为某一值的路径
		// 题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所
		// 有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

		#include <cstdio>
		#include "..\Utilities\BinaryTree.h"
		#include <vector>

		void FindPath(BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum);

		void FindPath(BinaryTreeNode* pRoot, int expectedSum)
		{
			if(pRoot == nullptr)
				return;

			std::vector<int> path;
			int currentSum = 0;
			FindPath(pRoot, expectedSum, path, currentSum);
		}

		void FindPath
		(
			BinaryTreeNode*   pRoot,        
			int               expectedSum,  
			std::vector<int>& path,         
			int&              currentSum
		)
		{
			currentSum += pRoot->m_nValue;
			path.push_back(pRoot->m_nValue);

			// 如果是叶结点,并且路径上结点的和等于输入的值
			// 打印出这条路径
			bool isLeaf = pRoot->m_pLeft == nullptr && pRoot->m_pRight == nullptr;
			if(currentSum == expectedSum && isLeaf)
			{
				printf("A path is found: ");
				std::vector<int>::iterator iter = path.begin();
				for(; iter != path.end(); ++ iter)
					printf("%d\t", *iter);
				
				printf("\n");
			}

			// 如果不是叶结点,则遍历它的子结点
			if(pRoot->m_pLeft != nullptr)
				FindPath(pRoot->m_pLeft, expectedSum, path, currentSum);
			if(pRoot->m_pRight != nullptr)
				FindPath(pRoot->m_pRight, expectedSum, path, currentSum);

			// 在返回到父结点之前,在路径上删除当前结点,
			// 并在currentSum中减去当前结点的值
			currentSum -= pRoot->m_nValue;
			path.pop_back();
		} 

		// ====================测试代码====================
		void Test(char* testName, BinaryTreeNode* pRoot, int expectedSum)
		{
			if(testName != nullptr)
				printf("%s begins:\n", testName);

			FindPath(pRoot, expectedSum);

			printf("\n");
		}

		//            10
		//         /      \
		//        5        12
		//       /\        
		//      4  7     
		// 有两条路径上的结点和为22
		void Test1()
		{
			BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);

			ConnectTreeNodes(pNode10, pNode5, pNode12);
			ConnectTreeNodes(pNode5, pNode4, pNode7);

			printf("Two paths should be found in Test1.\n");
			Test("Test1", pNode10, 22);

			DestroyTree(pNode10);
		}

		//            10
		//         /      \
		//        5        12
		//       /\        
		//      4  7     
		// 没有路径上的结点和为15
		void Test2()
		{
			BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);

			ConnectTreeNodes(pNode10, pNode5, pNode12);
			ConnectTreeNodes(pNode5, pNode4, pNode7);

			printf("No paths should be found in Test2.\n");
			Test("Test2", pNode10, 15);

			DestroyTree(pNode10);
		}

		//               5
		//              /
		//             4
		//            /
		//           3
		//          /
		//         2
		//        /
		//       1
		// 有一条路径上面的结点和为15
		void Test3()
		{
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

			ConnectTreeNodes(pNode5, pNode4, nullptr);
			ConnectTreeNodes(pNode4, pNode3, nullptr);
			ConnectTreeNodes(pNode3, pNode2, nullptr);
			ConnectTreeNodes(pNode2, pNode1, nullptr);

			printf("One path should be found in Test3.\n");
			Test("Test3", pNode5, 15);

			DestroyTree(pNode5);
		}

		// 1
		//  \
		//   2
		//    \
		//     3
		//      \
		//       4
		//        \
		//         5
		// 没有路径上面的结点和为16
		void Test4()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			ConnectTreeNodes(pNode1, nullptr, pNode2);
			ConnectTreeNodes(pNode2, nullptr, pNode3);
			ConnectTreeNodes(pNode3, nullptr, pNode4);
			ConnectTreeNodes(pNode4, nullptr, pNode5);

			printf("No paths should be found in Test4.\n");
			Test("Test4", pNode1, 16);

			DestroyTree(pNode1);
		}

		// 树中只有1个结点
		void Test5()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

			printf("One path should be found in Test5.\n");
			Test("Test5", pNode1, 1);

			DestroyTree(pNode1);
		}

		// 树中没有结点
		void Test6()
		{
			printf("No paths should be found in Test6.\n");
			Test("Test6", nullptr, 0);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();
			Test6();

			return 0;
		}

36. 面试题36:二叉搜索树与双向链表

			/*******************************************************************
			Copyright(c) 2016, Harry He
			All rights reserved.

			Distributed under the BSD license.
			(See accompanying file LICENSE.txt at
			https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
			*******************************************************************/

			//==================================================================
			// 《剑指Offer——名企面试官精讲典型编程题》代码
			// 作者:何海涛
			//==================================================================

			// 面试题36:二叉搜索树与双向链表
			// 题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求
			// 不能创建任何新的结点,只能调整树中结点指针的指向。

			#include <cstdio>
			#include "..\Utilities\BinaryTree.h"

			void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList);

			BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree)
			{
				BinaryTreeNode *pLastNodeInList = nullptr;
				ConvertNode(pRootOfTree, &pLastNodeInList);

				// pLastNodeInList指向双向链表的尾结点,
				// 我们需要返回头结点
				BinaryTreeNode *pHeadOfList = pLastNodeInList;
				while(pHeadOfList != nullptr && pHeadOfList->m_pLeft != nullptr)
					pHeadOfList = pHeadOfList->m_pLeft;

				return pHeadOfList;
			}

			void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList)
			{
				if(pNode == nullptr)
					return;

				BinaryTreeNode *pCurrent = pNode;

				if (pCurrent->m_pLeft != nullptr)
					ConvertNode(pCurrent->m_pLeft, pLastNodeInList);

				pCurrent->m_pLeft = *pLastNodeInList; 
				if(*pLastNodeInList != nullptr)
					(*pLastNodeInList)->m_pRight = pCurrent;

				*pLastNodeInList = pCurrent;

				if (pCurrent->m_pRight != nullptr)
					ConvertNode(pCurrent->m_pRight, pLastNodeInList);
			}

			// ====================测试代码====================
			void PrintDoubleLinkedList(BinaryTreeNode* pHeadOfList)
			{
				BinaryTreeNode* pNode = pHeadOfList;

				printf("The nodes from left to right are:\n");
				while(pNode != nullptr)
				{
					printf("%d\t", pNode->m_nValue);

					if(pNode->m_pRight == nullptr)
						break;
					pNode = pNode->m_pRight;
				}

				printf("\nThe nodes from right to left are:\n");
				while(pNode != nullptr)
				{
					printf("%d\t", pNode->m_nValue);

					if(pNode->m_pLeft == nullptr)
						break;
					pNode = pNode->m_pLeft;
				}

				printf("\n");
			}

			void DestroyList(BinaryTreeNode* pHeadOfList)
			{
				BinaryTreeNode* pNode = pHeadOfList;
				while(pNode != nullptr)
				{
					BinaryTreeNode* pNext = pNode->m_pRight;

					delete pNode;
					pNode = pNext;
				}
			}

			void Test(char* testName, BinaryTreeNode* pRootOfTree)
			{
				if(testName != nullptr)
					printf("%s begins:\n", testName);

				PrintTree(pRootOfTree);

				BinaryTreeNode* pHeadOfList = Convert(pRootOfTree);

				PrintDoubleLinkedList(pHeadOfList);
			}

			//            10
			//         /      \
			//        6        14
			//       /\        /\
			//      4  8     12  16
			void Test1()
			{
				BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode14 = CreateBinaryTreeNode(14);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
				BinaryTreeNode* pNode16 = CreateBinaryTreeNode(16);

				ConnectTreeNodes(pNode10, pNode6, pNode14);
				ConnectTreeNodes(pNode6, pNode4, pNode8);
				ConnectTreeNodes(pNode14, pNode12, pNode16);

				Test("Test1", pNode10);

				DestroyList(pNode4);
			}

			//               5
			//              /
			//             4
			//            /
			//           3
			//          /
			//         2
			//        /
			//       1
			void Test2()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

				ConnectTreeNodes(pNode5, pNode4, nullptr);
				ConnectTreeNodes(pNode4, pNode3, nullptr);
				ConnectTreeNodes(pNode3, pNode2, nullptr);
				ConnectTreeNodes(pNode2, pNode1, nullptr);

				Test("Test2", pNode5);

				DestroyList(pNode1);
			}

			// 1
			//  \
			//   2
			//    \
			//     3
			//      \
			//       4
			//        \
			//         5
			void Test3()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode1, nullptr, pNode2);
				ConnectTreeNodes(pNode2, nullptr, pNode3);
				ConnectTreeNodes(pNode3, nullptr, pNode4);
				ConnectTreeNodes(pNode4, nullptr, pNode5);

				Test("Test3", pNode1);

				DestroyList(pNode1);
			}

			// 树中只有1个结点
			void Test4()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
				Test("Test4", pNode1);

				DestroyList(pNode1);
			}

			// 树中没有结点
			void Test5()
			{
				Test("Test5", nullptr);
			}

			int main(int argc, char* argv[])
			{
				Test1();
				Test2();
				Test3();
				Test4();
				Test5();

				return 0;
			}

37. 面试题37:序列化二叉树

			/*******************************************************************
			Copyright(c) 2016, Harry He
			All rights reserved.

			Distributed under the BSD license.
			(See accompanying file LICENSE.txt at
			https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
			*******************************************************************/

			//==================================================================
			// 《剑指Offer——名企面试官精讲典型编程题》代码
			// 作者:何海涛
			//==================================================================

			// 面试题37:序列化二叉树
			// 题目:请实现两个函数,分别用来序列化和反序列化二叉树。

			#include <cstdio>
			#include "..\Utilities\BinaryTree.h"
			#include <iostream>
			#include <fstream>

			using namespace std;

			void Serialize(const BinaryTreeNode* pRoot, ostream& stream)
			{
				if(pRoot == nullptr)
				{
					stream << "$,";
					return;
				}

				stream << pRoot->m_nValue << ',';
				Serialize(pRoot->m_pLeft, stream);
				Serialize(pRoot->m_pRight, stream);
			}

			bool ReadStream(istream& stream, int* number)
			{
				if(stream.eof())
					return false;

				char buffer[32];
				buffer[0] = '\0';

				char ch;
				stream >> ch;
				int i = 0;
				while(!stream.eof() && ch != ',')
				{
					buffer[i++] = ch;
					stream >> ch;
				}

				bool isNumeric = false;
				if(i > 0 && buffer[0] != '$')
				{
					*number = atoi(buffer);
					isNumeric = true;
				}

				return isNumeric;
			}

			void Deserialize(BinaryTreeNode** pRoot, istream& stream)
			{
				int number;
				if(ReadStream(stream, &number))
				{
					*pRoot = new BinaryTreeNode();
					(*pRoot)->m_nValue = number;
					(*pRoot)->m_pLeft = nullptr;
					(*pRoot)->m_pRight = nullptr;

					Deserialize(&((*pRoot)->m_pLeft), stream);
					Deserialize(&((*pRoot)->m_pRight), stream);
				}
			}

			// ==================== Test Code ====================
			bool isSameTree(const BinaryTreeNode* pRoot1, const BinaryTreeNode* pRoot2)
			{
				if(pRoot1 == nullptr && pRoot2 == nullptr)
					return true;

				if(pRoot1 == nullptr || pRoot2 == nullptr)
					return false;

				if(pRoot1->m_nValue != pRoot2->m_nValue)
					return false;

				return isSameTree(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
					isSameTree(pRoot1->m_pRight, pRoot2->m_pRight);
			}

			void Test(const char* testName, const BinaryTreeNode* pRoot)
			{
				if(testName != nullptr)
					printf("%s begins: \n", testName);

				PrintTree(pRoot);

				char* fileName = "test.txt";
				ofstream fileOut;
				fileOut.open(fileName);

				Serialize(pRoot, fileOut);
				fileOut.close();

				// print the serialized file
				ifstream fileIn1;
				char ch;
				fileIn1.open(fileName);
				while(!fileIn1.eof())
				{
					fileIn1 >> ch;
					cout << ch;
				}
				fileIn1.close();
				cout << endl;

				ifstream fileIn2;
				fileIn2.open(fileName);
				BinaryTreeNode* pNewRoot = nullptr;
				Deserialize(&pNewRoot, fileIn2);
				fileIn2.close();

				PrintTree(pNewRoot);

				if(isSameTree(pRoot, pNewRoot))
					printf("The deserialized tree is same as the oritinal tree.\n\n");
				else
					printf("The deserialized tree is NOT same as the oritinal tree.\n\n");

				DestroyTree(pNewRoot);
			}

			//            8
			//        6      10
			//       5 7    9  11
			void Test1()
			{
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

				ConnectTreeNodes(pNode8, pNode6, pNode10);
				ConnectTreeNodes(pNode6, pNode5, pNode7);
				ConnectTreeNodes(pNode10, pNode9, pNode11);

				Test("Test1", pNode8);

				DestroyTree(pNode8);
			}

			//            5
			//          4
			//        3
			//      2
			void Test2()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNode5, pNode4, nullptr);
				ConnectTreeNodes(pNode4, pNode3, nullptr);
				ConnectTreeNodes(pNode3, pNode2, nullptr);

				Test("Test2", pNode5);

				DestroyTree(pNode5);
			}

			//        5
			//         4
			//          3
			//           2
			void Test3()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);

				ConnectTreeNodes(pNode5, nullptr, pNode4);
				ConnectTreeNodes(pNode4, nullptr, pNode3);
				ConnectTreeNodes(pNode3, nullptr, pNode2);

				Test("Test3", pNode5);

				DestroyTree(pNode5);
			}

			void Test4()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

				Test("Test4", pNode5);

				DestroyTree(pNode5);
			}

			void Test5()
			{
				Test("Test5", nullptr);
			}

			//        5
			//         5
			//          5
			//         5
			//        5
			//       5 5
			//      5   5
			void Test6()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode61 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode62 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode71 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode72 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode1, nullptr, pNode2);
				ConnectTreeNodes(pNode2, nullptr, pNode3);
				ConnectTreeNodes(pNode3, pNode4, nullptr);
				ConnectTreeNodes(pNode4, pNode5, nullptr);
				ConnectTreeNodes(pNode5, pNode61, pNode62);
				ConnectTreeNodes(pNode61, pNode71, nullptr);
				ConnectTreeNodes(pNode62, nullptr, pNode72);

				Test("Test6", pNode1);

				DestroyTree(pNode1);
			}

			int main(int argc, char* argv[])
			{
				Test1();
				Test2();
				Test3();
				Test4();
				Test5();
				Test6();

				return 0;
			}

54. 面试题54:二叉搜索树的第k个结点

			/*******************************************************************
			Copyright(c) 2016, Harry He
			All rights reserved.

			Distributed under the BSD license.
			(See accompanying file LICENSE.txt at
			https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
			*******************************************************************/

			//==================================================================
			// 《剑指Offer——名企面试官精讲典型编程题》代码
			// 作者:何海涛
			//==================================================================

			// 面试题54:二叉搜索树的第k个结点
			// 题目:给定一棵二叉搜索树,请找出其中的第k大的结点。

			#include <cstdio>
			#include "../Utilities/BinaryTree.h"

			const BinaryTreeNode* KthNodeCore(const BinaryTreeNode* pRoot, unsigned int& k);

			const BinaryTreeNode* KthNode(const BinaryTreeNode* pRoot, unsigned int k)
			{
				if(pRoot == nullptr || k == 0)
					return nullptr;

				return KthNodeCore(pRoot, k);
			}

			const BinaryTreeNode* KthNodeCore(const BinaryTreeNode* pRoot, unsigned int& k)
			{
				const BinaryTreeNode* target = nullptr;

				if(pRoot->m_pLeft != nullptr)
					target = KthNodeCore(pRoot->m_pLeft, k);

				if(target == nullptr)
				{
					if(k == 1)
						target = pRoot;

					k--;
				}

				if(target == nullptr && pRoot->m_pRight != nullptr)
					target = KthNodeCore(pRoot->m_pRight, k);

				return target;
			}

			// ====================测试代码====================
			void Test(const char* testName, const BinaryTreeNode* pRoot, unsigned int k, bool isNull, int expected)
			{
				if(testName != nullptr)
					printf("%s begins: ", testName);

				const BinaryTreeNode* pTarget = KthNode(pRoot, k);
				if((isNull && pTarget == nullptr) || (!isNull && pTarget->m_nValue == expected))
					printf("Passed.\n");
				else
					printf("FAILED.\n");
			}

			//            8
			//        6      10
			//       5 7    9  11
			void TestA()
			{
				BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
				BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
				BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
				BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
				BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

				ConnectTreeNodes(pNode8, pNode6, pNode10);
				ConnectTreeNodes(pNode6, pNode5, pNode7);
				ConnectTreeNodes(pNode10, pNode9, pNode11);

				Test("TestA0", pNode8, 0, true, -1);
				Test("TestA1", pNode8, 1, false, 5);
				Test("TestA2", pNode8, 2, false, 6);
				Test("TestA3", pNode8, 3, false, 7);
				Test("TestA4", pNode8, 4, false, 8);
				Test("TestA5", pNode8, 5, false, 9);
				Test("TestA6", pNode8, 6, false, 10);
				Test("TestA7", pNode8, 7, false, 11);
				Test("TestA8", pNode8, 8, true, -1);

				DestroyTree(pNode8);

				printf("\n\n");
			}

			//               5
			//              /
			//             4
			//            /
			//           3
			//          /
			//         2
			//        /
			//       1
			void TestB()
			{
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

				ConnectTreeNodes(pNode5, pNode4, nullptr);
				ConnectTreeNodes(pNode4, pNode3, nullptr);
				ConnectTreeNodes(pNode3, pNode2, nullptr);
				ConnectTreeNodes(pNode2, pNode1, nullptr);

				Test("TestB0", pNode5, 0, true, -1);
				Test("TestB1", pNode5, 1, false, 1);
				Test("TestB2", pNode5, 2, false, 2);
				Test("TestB3", pNode5, 3, false, 3);
				Test("TestB4", pNode5, 4, false, 4);
				Test("TestB5", pNode5, 5, false, 5);
				Test("TestB6", pNode5, 6, true, -1);

				DestroyTree(pNode5);

				printf("\n\n");
			}

			// 1
			//  \
			//   2
			//    \
			//     3
			//      \
			//       4
			//        \
			//         5
			void TestC()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
				BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
				BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
				BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
				BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

				ConnectTreeNodes(pNode1, nullptr, pNode2);
				ConnectTreeNodes(pNode2, nullptr, pNode3);
				ConnectTreeNodes(pNode3, nullptr, pNode4);
				ConnectTreeNodes(pNode4, nullptr, pNode5);

				Test("TestC0", pNode1, 0, true, -1);
				Test("TestC1", pNode1, 1, false, 1);
				Test("TestC2", pNode1, 2, false, 2);
				Test("TestC3", pNode1, 3, false, 3);
				Test("TestC4", pNode1, 4, false, 4);
				Test("TestC5", pNode1, 5, false, 5);
				Test("TestC6", pNode1, 6, true, -1);

				DestroyTree(pNode1);

				printf("\n\n");
			}

			// There is only one node in a tree
			void TestD()
			{
				BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

				Test("TestD0", pNode1, 0, true, -1);
				Test("TestD1", pNode1, 1, false, 1);
				Test("TestD2", pNode1, 2, true, -1);

				DestroyTree(pNode1);

				printf("\n\n");
			}

			// empty tree
			void TestE()
			{
				Test("TestE0", nullptr, 0, true, -1);
				Test("TestE1", nullptr, 1, true, -1);

				printf("\n\n");
			}

			int main(int argc, char* argv[])
			{
				TestA();
				TestB();
				TestC();
				TestD();
				TestE();
			}

55. 面试题55:二叉树的深度

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题55(一):二叉树的深度
		// 题目:输入一棵二叉树的根结点,求该树的深度。从根结点到叶结点依次经过的
		// 结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

		#include <cstdio>
		#include "..\Utilities\BinaryTree.h"

		int TreeDepth(const BinaryTreeNode* pRoot)
		{
			if(pRoot == nullptr)
				return 0;

			int nLeft = TreeDepth(pRoot->m_pLeft);
			int nRight = TreeDepth(pRoot->m_pRight);

			return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
		}

		// ====================测试代码====================
		void Test(const char* testName, const BinaryTreeNode* pRoot, int expected)
		{
			int result = TreeDepth(pRoot);
			if(expected == result)
				printf("%s passed.\n", testName);
			else
				printf("%s FAILED.\n", testName);
		}

		//            1
		//         /      \
		//        2        3
		//       /\         \
		//      4  5         6
		//        /
		//       7
		void Test1()
		{
			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, nullptr, pNode6);
			ConnectTreeNodes(pNode5, pNode7, nullptr);

			Test("Test1", pNode1, 4);

			DestroyTree(pNode1);
		}

		//               1
		//              /
		//             2
		//            /
		//           3
		//          /
		//         4
		//        /
		//       5
		void Test2()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			ConnectTreeNodes(pNode1, pNode2, nullptr);
			ConnectTreeNodes(pNode2, pNode3, nullptr);
			ConnectTreeNodes(pNode3, pNode4, nullptr);
			ConnectTreeNodes(pNode4, pNode5, nullptr);

			Test("Test2", pNode1, 5);

			DestroyTree(pNode1);
		}

		// 1
		//  \
		//   2
		//    \
		//     3
		//      \
		//       4
		//        \
		//         5
		void Test3()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			ConnectTreeNodes(pNode1, nullptr, pNode2);
			ConnectTreeNodes(pNode2, nullptr, pNode3);
			ConnectTreeNodes(pNode3, nullptr, pNode4);
			ConnectTreeNodes(pNode4, nullptr, pNode5);

			Test("Test3", pNode1, 5);

			DestroyTree(pNode1);
		}

		// 树中只有1个结点
		void Test4()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			Test("Test4", pNode1, 1);

			DestroyTree(pNode1);
		}

		// 树中没有结点
		void Test5()
		{
			Test("Test5", nullptr, 0);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();

			return 0;
		}

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题55(二):平衡二叉树
		// 题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树。如果某二叉树中
		// 任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

		#include <cstdio>
		#include "..\Utilities\BinaryTree.h"

		// ====================方法1====================
		int TreeDepth(const BinaryTreeNode* pRoot)
		{
			if(pRoot == nullptr)
				return 0;

			int nLeft = TreeDepth(pRoot->m_pLeft);
			int nRight = TreeDepth(pRoot->m_pRight);

			return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
		}

		bool IsBalanced_Solution1(const BinaryTreeNode* pRoot)
		{
			if(pRoot == nullptr)
				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_Solution1(pRoot->m_pLeft) 
				&& IsBalanced_Solution1(pRoot->m_pRight);
		}

		// ====================方法2====================
		bool IsBalanced(const BinaryTreeNode* pRoot, int* pDepth);

		bool IsBalanced_Solution2(const BinaryTreeNode* pRoot)
		{
			int depth = 0;
			return IsBalanced(pRoot, &depth);
		}

		bool IsBalanced(const BinaryTreeNode* pRoot, int* pDepth)
		{
			if(pRoot == nullptr)
			{
				*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;
		}

		// ====================测试代码====================
		void Test(const char* testName, const BinaryTreeNode* pRoot, bool expected)
		{
			if(testName != nullptr)
				printf("%s begins:\n", testName);

			printf("Solution1 begins: ");
			if(IsBalanced_Solution1(pRoot) == expected)
				printf("Passed.\n");
			else
				printf("Failed.\n");

			printf("Solution2 begins: ");
			if(IsBalanced_Solution2(pRoot) == expected)
				printf("Passed.\n");
			else
				printf("Failed.\n");
		}

		// 完全二叉树
		//             1
		//         /      \
		//        2        3
		//       /\       / \
		//      4  5     6   7
		void Test1()
		{
			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, pNode6, pNode7);

			Test("Test1", pNode1, true);

			DestroyTree(pNode1);
		}

		// 不是完全二叉树,但是平衡二叉树
		//             1
		//         /      \
		//        2        3
		//       /\         \
		//      4  5         6
		//        /
		//       7
		void Test2()
		{
			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, nullptr, pNode6);
			ConnectTreeNodes(pNode5, pNode7, nullptr);

			Test("Test2", pNode1, true);

			DestroyTree(pNode1);
		}

		// 不是平衡二叉树
		//             1
		//         /      \
		//        2        3
		//       /\         
		//      4  5        
		//        /
		//       6
		void Test3()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
			BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);

			ConnectTreeNodes(pNode1, pNode2, pNode3);
			ConnectTreeNodes(pNode2, pNode4, pNode5);
			ConnectTreeNodes(pNode5, pNode6, nullptr);

			Test("Test3", pNode1, false);

			DestroyTree(pNode1);
		}


		//               1
		//              /
		//             2
		//            /
		//           3
		//          /
		//         4
		//        /
		//       5
		void Test4()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			ConnectTreeNodes(pNode1, pNode2, nullptr);
			ConnectTreeNodes(pNode2, pNode3, nullptr);
			ConnectTreeNodes(pNode3, pNode4, nullptr);
			ConnectTreeNodes(pNode4, pNode5, nullptr);

			Test("Test4", pNode1, false);

			DestroyTree(pNode1);
		}

		// 1
		//  \
		//   2
		//    \
		//     3
		//      \
		//       4
		//        \
		//         5
		void Test5()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
			BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
			BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
			BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

			ConnectTreeNodes(pNode1, nullptr, pNode2);
			ConnectTreeNodes(pNode2, nullptr, pNode3);
			ConnectTreeNodes(pNode3, nullptr, pNode4);
			ConnectTreeNodes(pNode4, nullptr, pNode5);

			Test("Test5", pNode1, false);

			DestroyTree(pNode1);
		}

		// 树中只有1个结点
		void Test6()
		{
			BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
			Test("Test6", pNode1, true);

			DestroyTree(pNode1);
		}

		// 树中没有结点
		void Test7()
		{
			Test("Test7", nullptr, true);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();
			Test5();
			Test6();
			Test7();

			return 0;
		}

68. 面试题68:树中两个结点的最低公共祖先

		/*******************************************************************
		Copyright(c) 2016, Harry He
		All rights reserved.

		Distributed under the BSD license.
		(See accompanying file LICENSE.txt at
		https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
		*******************************************************************/

		//==================================================================
		// 《剑指Offer——名企面试官精讲典型编程题》代码
		// 作者:何海涛
		//==================================================================

		// 面试题68:树中两个结点的最低公共祖先
		// 题目:输入两个树结点,求它们的最低公共祖先。

		#include <cstdio>
		#include "..\Utilities\Tree.h"
		#include <list>

		using namespace std;

		bool GetNodePath(const TreeNode* pRoot, const TreeNode* pNode, list<const TreeNode*>& path)
		{
			if(pRoot == pNode)
				return true;
		 
			path.push_back(pRoot);
		 
			bool found = false;

			vector<TreeNode*>::const_iterator i = pRoot->m_vChildren.begin();
			while(!found && i < pRoot->m_vChildren.end())
			{
				found = GetNodePath(*i, pNode, path);
				++i;
			}
		 
			if(!found)
				path.pop_back();
		 
			return found;
		}

		const TreeNode* GetLastCommonNode
		(
			const list<const TreeNode*>& path1, 
			const list<const TreeNode*>& path2
		)
		{
			list<const TreeNode*>::const_iterator iterator1 = path1.begin();
			list<const TreeNode*>::const_iterator iterator2 = path2.begin();
			
			const TreeNode* pLast = nullptr;
		 
			while(iterator1 != path1.end() && iterator2 != path2.end())
			{
				if(*iterator1 == *iterator2)
					pLast = *iterator1;
		 
				iterator1++;
				iterator2++;
			}
		 
			return pLast;
		}

		const TreeNode* GetLastCommonParent(const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2)
		{
			if(pRoot == nullptr || pNode1 == nullptr || pNode2 == nullptr)
				return nullptr;
		 
			list<const TreeNode*> path1;
			GetNodePath(pRoot, pNode1, path1);
		 
			list<const TreeNode*> path2;
			GetNodePath(pRoot, pNode2, path2);
		 
			return GetLastCommonNode(path1, path2);
		}

		// ====================测试代码====================
		void Test(const char* testName, const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2, TreeNode* pExpected)
		{
			if(testName != nullptr)
				printf("%s begins: ", testName);

			const TreeNode* pResult = GetLastCommonParent(pRoot, pNode1, pNode2);

			if((pExpected == nullptr && pResult == nullptr) || 
				(pExpected != nullptr && pResult != nullptr && pResult->m_nValue == pExpected->m_nValue))
				printf("Passed.\n");
			else
				printf("Failed.\n");
		}

		// 形状普通的树
		//              1
		//            /   \
		//           2     3
		//       /       \
		//      4         5
		//     / \      / |  \
		//    6   7    8  9  10
		void Test1()
		{
			TreeNode* pNode1 = CreateTreeNode(1);
			TreeNode* pNode2 = CreateTreeNode(2);
			TreeNode* pNode3 = CreateTreeNode(3);
			TreeNode* pNode4 = CreateTreeNode(4);
			TreeNode* pNode5 = CreateTreeNode(5);
			TreeNode* pNode6 = CreateTreeNode(6);
			TreeNode* pNode7 = CreateTreeNode(7);
			TreeNode* pNode8 = CreateTreeNode(8);
			TreeNode* pNode9 = CreateTreeNode(9);
			TreeNode* pNode10 = CreateTreeNode(10);

			ConnectTreeNodes(pNode1, pNode2);
			ConnectTreeNodes(pNode1, pNode3);

			ConnectTreeNodes(pNode2, pNode4);
			ConnectTreeNodes(pNode2, pNode5);

			ConnectTreeNodes(pNode4, pNode6);
			ConnectTreeNodes(pNode4, pNode7);

			ConnectTreeNodes(pNode5, pNode8);
			ConnectTreeNodes(pNode5, pNode9);
			ConnectTreeNodes(pNode5, pNode10);

			Test("Test1", pNode1, pNode6, pNode8, pNode2);
		}

		// 树退化成一个链表
		//               1
		//              /
		//             2
		//            /
		//           3
		//          /
		//         4
		//        /
		//       5
		void Test2()
		{
			TreeNode* pNode1 = CreateTreeNode(1);
			TreeNode* pNode2 = CreateTreeNode(2);
			TreeNode* pNode3 = CreateTreeNode(3);
			TreeNode* pNode4 = CreateTreeNode(4);
			TreeNode* pNode5 = CreateTreeNode(5);

			ConnectTreeNodes(pNode1, pNode2);
			ConnectTreeNodes(pNode2, pNode3);
			ConnectTreeNodes(pNode3, pNode4);
			ConnectTreeNodes(pNode4, pNode5);

			Test("Test2", pNode1, pNode5, pNode4, pNode3);
		}

		// 树退化成一个链表,一个结点不在树中
		//               1
		//              /
		//             2
		//            /
		//           3
		//          /
		//         4
		//        /
		//       5
		void Test3()

		{
			TreeNode* pNode1 = CreateTreeNode(1);
			TreeNode* pNode2 = CreateTreeNode(2);
			TreeNode* pNode3 = CreateTreeNode(3);
			TreeNode* pNode4 = CreateTreeNode(4);
			TreeNode* pNode5 = CreateTreeNode(5);

			ConnectTreeNodes(pNode1, pNode2);
			ConnectTreeNodes(pNode2, pNode3);
			ConnectTreeNodes(pNode3, pNode4);
			ConnectTreeNodes(pNode4, pNode5);

			TreeNode* pNode6 = CreateTreeNode(6);

			Test("Test3", pNode1, pNode5, pNode6, nullptr);
		}

		// 输入nullptr
		void Test4()
		{
			Test("Test4", nullptr, nullptr, nullptr, nullptr);
		}

		int main(int argc, char* argv[])
		{
			Test1();
			Test2();
			Test3();
			Test4();

			return 0;
		}
posted @ 2019-12-11 19:57  风御之举  阅读(35)  评论(0编辑  收藏  举报