题目:请完成函数,输入一个二叉树,该函数输出它的镜像。
思路:可能没有听说过书的镜像,但是可以通过画图等来找灵感。就像照镜子一样,人的左边和右边交换了。
如图:
通过如下图变化就可以由左图得到右图:
总体来说:将所有的非叶子节点的左右子树交换。由于交换的过程惊人的一直,因此可以采用递归。
C++代码:
#include<iostream> using namespace std; struct BinaryTreeNode { int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; 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=NULL; if(startPreorder==endPreorder) { if(startInorder==endInorder&&*startPreorder==*startInorder) { return root; } else throw std::exception("Invalid put!"); } //通过中序遍历序列找到根节点 int* rootInorder=startInorder; while(rootInorder<=endInorder&&*rootInorder!=rootValue) { ++rootInorder; } if(rootInorder==endInorder&&*rootInorder!=rootValue) { throw std::exception("Invalid put"); } int leftLength=rootInorder-startInorder; int rightLength=endInorder-rootInorder; int* leftPreorderEnd=startPreorder+leftLength; if(leftLength>0) { //递归构建左子树 root->m_pLeft=ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1); } if(rightLength>0) { //递归构建右子树 root->m_pRight=ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder); } return root; } BinaryTreeNode* Construct(int* preorder,int* inorder,int length) { if(preorder==NULL||inorder==NULL||length<=0) { throw std::exception("Invalid put!"); } return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1); } void swrap_element(BinaryTreeNode** left,BinaryTreeNode** right) { BinaryTreeNode* temp=*left; *left=*right; *right=temp; } void MirrorRecursively(BinaryTreeNode* pNode) { if(pNode==NULL||(pNode->m_pLeft==NULL&&pNode->m_pRight)) return; swrap_element(&pNode->m_pLeft,&pNode->m_pRight); if(pNode->m_pLeft!=NULL) MirrorRecursively(pNode->m_pLeft); if(pNode->m_pRight!=NULL) MirrorRecursively(pNode->m_pRight); } void PrintTreeNode(BinaryTreeNode* pNode) { if(pNode != NULL) { printf("value of this node is: %d ", pNode->m_nValue); if(pNode->m_pLeft != NULL) printf("value of its left child is: %d. ", pNode->m_pLeft->m_nValue); else printf("left child is null. "); if(pNode->m_pRight != NULL) printf("value of its right child is: %d. ", pNode->m_pRight->m_nValue); else printf("right child is null. "); } else { printf("this node is null. "); } printf(" "); } //递归打印左右子树 void PrintTree(BinaryTreeNode* pRoot) { PrintTreeNode(pRoot); if(pRoot != NULL) { if(pRoot->m_pLeft != NULL) PrintTree(pRoot->m_pLeft); if(pRoot->m_pRight != NULL) PrintTree(pRoot->m_pRight); } } //递归删除左右子树 void DestroyTree(BinaryTreeNode* pRoot) { if(pRoot != NULL) { BinaryTreeNode* pLeft = pRoot->m_pLeft; BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot; pRoot = NULL; DestroyTree(pLeft); DestroyTree(pRight); } } void main() { const int length1 = 8; int preorder1[length1] = {1, 2, 4, 7, 3, 5, 6, 8}; int inorder1[length1] = {4, 7, 2, 1, 5, 3, 8, 6}; BinaryTreeNode *root1 = Construct(preorder1, inorder1, length1); PrintTree(root1); MirrorRecursively(root1); PrintTree(root1); }
Java代码:
public class MirrorRecursively { public static class BinaryTreeNode{ int m_nValue; BinaryTreeNode m_pLeft; BinaryTreeNode m_pRight; } public static BinaryTreeNode ConstructBiTree(int[] preOrder,int start,int[] inOrder,int end,int length){ if(preOrder==null||inOrder==null||preOrder.length!=inOrder.length||length<=0) return null; int value=preOrder[start]; BinaryTreeNode root=new BinaryTreeNode(); root.m_nValue=value; root.m_pLeft=root.m_pRight=null; //当整棵树只有一个节点的情况 if(length==1){ if(value==inOrder[end]) return root; else throw new RuntimeException("inVaild put"); } //在中序遍历的数组中找到根节点 int i=0; while(i<length){ if(value==inOrder[end-i]){ break; } i++; } if(i==length) throw new RuntimeException("inVaild put!"); root.m_pLeft=ConstructBiTree(preOrder,start+1,inOrder,end-i-1,length-i-1); root.m_pRight=ConstructBiTree(preOrder,start+length-i,inOrder,end,i); return root; } public static void printNode(BinaryTreeNode pNode){ if(pNode==null) return; System.out.println("the node is:"+pNode.m_nValue); if(pNode.m_pLeft!=null) System.out.println("the left node is:"+pNode.m_pLeft.m_nValue); else System.out.println("the left node is null"); if(pNode.m_pRight!=null) System.out.println("the right node is:"+pNode.m_pRight.m_nValue); else System.out.println("the right node is null"); } public static void printBiTree(BinaryTreeNode pNode){ printNode(pNode); if(pNode.m_pLeft!=null) printBiTree(pNode.m_pLeft); if(pNode.m_pRight!=null) printBiTree(pNode.m_pRight); } //二叉树的镜像 public static void MirrorRecursive(BinaryTreeNode pHead){ if(pHead==null||(pHead.m_pLeft==null&&pHead.m_pRight==null)) return; BinaryTreeNode pTemp=pHead.m_pLeft; pHead.m_pLeft=pHead.m_pRight; pHead.m_pRight=pTemp; if(pHead.m_pLeft!=null) MirrorRecursive(pHead.m_pLeft); if(pHead.m_pRight!=null) MirrorRecursive(pHead.m_pRight); } public static void main(String[] args){ int[] preOrder={3,6}; int[] inOrder={6,3}; BinaryTreeNode pNode=ConstructBiTree(preOrder,0,inOrder,1,preOrder.length); printBiTree(pNode); MirrorRecursive(pNode); printBiTree(pNode); } }