《剑指Offer》面试题19:二叉树的镜像
题目描述
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
二叉树结点定义如下:
struct BinaryTreeNode { int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; };
解题思路
求一棵树的镜像的过程:我们先前序遍历这棵树的每个结点,如果遍历的结点有子结点,就交换它的两个子结点,当交换完所有的非叶子结点的左右子结点之后,我们就得到了镜像。
测试用例
代码
/* 《剑指Offer——名企面试官精讲典型编程题》代码 著作权所有者:何海涛*/ #include <iostream> #include <stack> using namespace std; struct BinaryTreeNode { int m_nValue; BinaryTreeNode *m_pLeft; BinaryTreeNode *m_pRight; }; BinaryTreeNode* CreateBinaryTreeNode(int value) { BinaryTreeNode* pNode = new BinaryTreeNode(); pNode->m_nValue = value; pNode->m_pLeft = NULL; pNode->m_pRight = NULL; return pNode; } void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) { if (pParent != NULL) { pParent->m_pLeft = pLeft; pParent->m_pRight = pRight; } } void PrintTreeNode(BinaryTreeNode* pNode) { if (pNode != NULL) { printf("value of this node is: %d\n", pNode->m_nValue); if (pNode->m_pLeft != NULL) 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 != NULL) 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 != NULL) { if (pRoot->m_pLeft != NULL) PrintTree(pRoot->m_pLeft); if (pRoot->m_pRight != NULL) PrintTree(pRoot->m_pRight); } } void DestroyTree(BinaryTreeNode* pRoot) { if (pRoot != NULL) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree(pLeft); DestroyTree(pRight); } } //=====================方法1:递归实现===================================== void MirrorRecursively(BinaryTreeNode *pNode) { if ((pNode == NULL) || (pNode->m_pLeft == NULL && 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); } //= == == == == == == == == == == 方法2:迭代实现 == == == == == == == == == == == == == == == == == == = void MirrorIteratively(BinaryTreeNode* pRoot) { if (pRoot == NULL) return; std::stack<BinaryTreeNode*> stackTreeNode; stackTreeNode.push(pRoot); while (stackTreeNode.size() > 0) { BinaryTreeNode *pNode = stackTreeNode.top(); stackTreeNode.pop(); if (pNode->m_pLeft != NULL && pNode->m_pRight != NULL) { 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, NULL); ConnectTreeNodes(pNode7, pNode6, NULL); ConnectTreeNodes(pNode6, pNode5, NULL); ConnectTreeNodes(pNode5, pNode4, NULL); 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, NULL, pNode7); ConnectTreeNodes(pNode7, NULL, pNode6); ConnectTreeNodes(pNode6, NULL, pNode5); ConnectTreeNodes(pNode5, NULL, 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 = NULL; 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() { Test1(); Test2(); Test3(); Test4(); Test5(); system("pause"); return 0; }