• 剑指offer--面试题6


    题目:由前序、中序遍历序列重建二叉树

    虽然思路能想到,但是实际写却无从下手。。。
    下面重现作者代码,多多实践。。。

    #include<exception>
    
    //首先定义二叉树节点
    struct BinaryTreeNode
    {
        int bt_Value;
        BinaryTreeNode* bt_pLeft;
        BinaryTreeNode* bt_pRight;
    };
    
    //核心函数:ConstructCore(int* StartPreOrder, int* EndPreOrder, int* StartInOrder, int* EndInOrder);
    BinaryTreeNode* ConstructCore(int* StartPreOrder, int* EndPreOrder, 
                                  int* StartInOrder, int* EndInOrder)
    //StartPreOrder,EndPreOrder为先序遍历序列的首尾;StartInOrder,EndInOrder为中序遍历序列的首尾
    //总体思路:1、先序遍历首元素即为根节点,创建根节点;
    //            2、中序遍历中寻找根节点,以此为界,前面为左子树,后面为右子树;
    //            3、函数递归以创建左子树和右子树;
    //            递归终止条件:StartPreOrder == EndPreOrder时,StartInOrder同时应等于EndInOrder,为叶子节点。
    
    //因Construct函数中已验证了各个指针项的合法性,所以ConstructCore不再验证。
    {
        //根据前序序列首元素创建根节点
        int RootValue = StartPreOrder[0];
        BinaryTreeNode* root = new BinaryTreeNode;
        root->bt_Value = RootValue;
        root->bt_pLeft = root->bt_pRight = NULL;
    
        //递归终止条件
        if(StartPreOrder == EndPreOrder)
        {
            if(StartInOrder == EndInOrder && *StartPreOrder == *StartInOrder)
                return root;  //该节点为叶子节点,创建子树结束
            else
                throw std::exception("Invalid Input!");
        }
    
        //在中序序列中寻找根节点位置
        int* rootInOrder = StartInOrder;
        while(rootInOrder <= EndInOrder && *rootInOrder != RootValue)
            rootInOrder++;
        if(rootInOrder > EndInOrder)
            throw std::exception("Invalid Input!");
        //确定左子树的节点个数
        int LeftTreeLength = rootInOrder - StartInOrder;
        int* LeftTreePreOrderEnd = StartPreOrder + LeftTreeLength;
        //创建左子树
        if(LeftTreeLength > 0 )
            root->bt_pLeft = ConstructCore(StartPreOrder+1,LeftTreePreOrderEnd,StartInOrder,rootInOrder-1);
        //创建右子树
        if(rootInOrder < EndInOrder)
            root->bt_pRight = ConstructCore(LeftTreePreOrderEnd+1,EndPreOrder,rootInOrder+1,EndInOrder);
        
        return root;
    }
    
    //调用该递归函数的Construct函数如下:
    BinaryTreeNode* Construct(int* PreOrder, int* InOrder, int length)
    {
        if(PreOrder == NULL || InOrder == NULL || length <= 0)
            return NULL;
        return ConstructCore(PreOrder,PreOrder+length-1,InOrder,InOrder+length-1);
    }
    //BinaryTree.cpp中的各个接口实现
    //1. 创建二叉树节点
    BinaryTreeNode* CreateBinaryTreeNode(int value)
    {
        BinaryTreeNode* pNode = new BinaryTreeNode;
        pNode->bt_Value = value;
        pNode->bt_pLeft = pNode->bt_pRight = NULL;
    
        return pNode;
    }
    
    //2. 连接树节点
    void ConnectBinaryTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
    {
        if(pParent != NULL)
        {
            pParent->bt_pLeft = pLeft;
            pParent->bt_pRight = pRight;
        }
        else
            return;
    }
    
    //3. 打印树节点及其孩子节点
    void PrintTreeNode(BinaryTreeNode* pNode)
    {
        if(pNode != NULL)
        {
            cout<<"The value of this node is: "<<pNode->bt_Value
                <<endl;
            if(pNode->bt_pLeft != NULL)
                cout<<"The value of the left-child node is: "<<pNode->bt_pLeft->bt_Value
                    <<endl;
            else
                cout<<"The left-child node is NULL!"<<endl;
            if(pNode->bt_pRight != NULL)
                cout<<"The value of the right-child node is: "<<pNode->bt_pRight->bt_Value
                    <<endl;
            else
                cout<<"The right-child node is NULL!"<<endl;
        }
        else
            cout<<"This node is NULL!"<<endl;
    }
    
    //4. 打印树 (逐三角打印)
    void PrintTree(BinaryTreeNode* pRoot)
    {
        PrintTreeNode(pRoot);
    
        if(pRoot != NULL)
        {
            if(pRoot->bt_pLeft != NULL)
                PrintTree(pRoot->bt_pLeft);
            if(pRoot->bt_pRight != NULL)
                PrintTree(pRoot->bt_pRight);
        }
    
    }
    
    //5. 销毁树
    void DestroyTree(BinaryTreeNode* pRoot)
    {
        if(pRoot != NULL)
        {
            BinaryTreeNode* pLeft = pRoot->bt_pLeft;
            BinaryTreeNode* pRight = pRoot->bt_pRight;
    
            delete pRoot;
            pRoot = NULL;
    
            DestroyTree(pLeft);
            DestroyTree(pRight);
        }
    }
    清醒时做事,糊涂时读书,大怒时睡觉,独处时思考; 做一个幸福的人,读书,旅行,努力工作,关心身体和心情,成为最好的自己 -- 共勉
  • 相关阅读:
    “main cannot be resolved or is not a field”解决方案
    .net学习笔记----有序集合SortedList、SortedList<TKey,TValue>、SortedDictionary<TKey,TValue>
    MVC学习笔记---ModelBinder
    MVC学习笔记---MVC框架执行顺序
    服务器知识----IIS架设问题
    C/C++学习笔记---primer基础知识
    C/C++学习笔记----指针的理解
    C#学习笔记-----C#枚举中的位运算权限分配
    CSS学习笔记----CSS3自定义字体图标
    Clr Via C#读书笔记----基元线程同步构造
  • 原文地址:https://www.cnblogs.com/hello-yz/p/3243710.html
Copyright © 2020-2023  润新知