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

思路:可能没有听说过书的镜像,但是可以通过画图等来找灵感。就像照镜子一样,人的左边和右边交换了。

如图:

剑指offer-第四章解决面试题的思路(二叉树的镜像)-LMLPHP

通过如下图变化就可以由左图得到右图:

剑指offer-第四章解决面试题的思路(二叉树的镜像)-LMLPHP

总体来说:将所有的非叶子节点的左右子树交换。由于交换的过程惊人的一直,因此可以采用递归。

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\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);
}
} 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);
} }
05-06 01:06