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


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

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

    如图:

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

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

    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);
        }
    
    }
  • 相关阅读:
    Java理论-Java高级
    Java理论-Java基础
    Java理论-JVM
    Nginx的使用总结
    修改tomcat端口号
    测试目录
    常用的设计模式汇总,超详细!
    Java高级程序员(5年左右)面试的题目集
    集合类--最详细的面试宝典--看这篇就够用了(java 1.8)
    Java面试宝典(2020版)
  • 原文地址:https://www.cnblogs.com/hupp/p/4587151.html
Copyright © 2020-2023  润新知