• 《剑指offer》第二十七题:二叉树的镜像


    // 面试题27:二叉树的镜像
    // 题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
    
    #include <cstdio>
    #include "BinaryTree.h"
    #include <stack>
    
    void MirrorRecursively(BinaryTreeNode* pNode) //自底向上
    {
        if (pNode == nullptr || (pNode->m_pLeft == nullptr && pNode->m_pRight == nullptr))
            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*> treeNodeStack; //存放未交换的根节点
        treeNodeStack.push(pRoot);
    
        while (treeNodeStack.size() > 0)
        {
            BinaryTreeNode* pNode = treeNodeStack.top();
            treeNodeStack.pop();
    
            //交换父节点的两个子节点
            BinaryTreeNode* pTemp = pNode->m_pLeft;
            pNode->m_pLeft = pNode->m_pRight;
            pNode->m_pRight = pTemp;
    
            if (pNode->m_pLeft)
                treeNodeStack.push(pNode->m_pLeft);
            if (pNode->m_pRight)
                treeNodeStack.push(pNode->m_pRight);
        }
    }
    // ====================测试代码====================
    // 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
    //            8
    //        6      10
    //       5 7    9  11
    void Test1()
    {
        printf("=====Test1 starts:=====
    ");
        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=====
    ");
        MirrorRecursively(pNode8);
        PrintTree(pNode8);
    
        printf("=====Test1: MirrorIteratively=====
    ");
        MirrorIteratively(pNode8);
        PrintTree(pNode8);
    
        DestroyTree(pNode8);
    }
    
    // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
    //            8
    //          7   
    //        6 
    //      5
    //    4
    void Test2()
    {
        printf("=====Test2 starts:=====
    ");
        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=====
    ");
        MirrorRecursively(pNode8);
        PrintTree(pNode8);
    
        printf("=====Test2: MirrorIteratively=====
    ");
        MirrorIteratively(pNode8);
        PrintTree(pNode8);
    
        DestroyTree(pNode8);
    }
    
    // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
    //            8
    //             7   
    //              6 
    //               5
    //                4
    void Test3()
    {
        printf("=====Test3 starts:=====
    ");
        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=====
    ");
        MirrorRecursively(pNode8);
        PrintTree(pNode8);
    
        printf("=====Test3: MirrorIteratively=====
    ");
        MirrorIteratively(pNode8);
        PrintTree(pNode8);
    
        DestroyTree(pNode8);
    }
    
    // 测试空二叉树:根结点为空指针
    void Test4()
    {
        printf("=====Test4 starts:=====
    ");
        BinaryTreeNode* pNode = nullptr;
    
        PrintTree(pNode);
    
        printf("=====Test4: MirrorRecursively=====
    ");
        MirrorRecursively(pNode);
        PrintTree(pNode);
    
        printf("=====Test4: MirrorIteratively=====
    ");
        MirrorIteratively(pNode);
        PrintTree(pNode);
    }
    
    // 测试只有一个结点的二叉树
    void Test5()
    {
        printf("=====Test5 starts:=====
    ");
        BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
    
        PrintTree(pNode8);
    
        printf("=====Test4: MirrorRecursively=====
    ");
        MirrorRecursively(pNode8);
        PrintTree(pNode8);
    
        printf("=====Test4: MirrorIteratively=====
    ");
        MirrorIteratively(pNode8);
        PrintTree(pNode8);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        Test5();
    
        return 0;
    }
    测试代码

    分析:基于循环的方法很巧妙。

    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    class Solution {
    public:
        void Mirror(TreeNode *pRoot) {
            
            if (pRoot == nullptr || (pRoot->left == nullptr && pRoot->right == nullptr))
                return;
            
            TreeNode* treeTemp = pRoot->right;
            pRoot->right = pRoot->left;
            pRoot->left = treeTemp;
                
            if (pRoot->left)
                Mirror(pRoot->left);
            if (pRoot->right)
                Mirror(pRoot->right);
        }
    };
    牛客网提交代码

  • 相关阅读:
    滚动条美化插件 nicescroll
    百度地图api
    Echarts的重点
    3月20号课堂随笔
    循环for语句
    有关一些CSS的基本内容
    HTML基本标签和一些注释的问题
    2018年3月17号的随堂笔记
    03.15补习
    for 的相关用法
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12584955.html
Copyright © 2020-2023  润新知