剑指offer-通过二叉树的前序序列和中序序列还原出二叉树

BinaryTree.h

/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//

typedef int ElemType;

struct BinaryTreeNode
{
    ElemType m_nValue;
    BinaryTreeNode*m_pLeft;
    BinaryTreeNode*m_pRight;
};

BinaryTreeNode*createBinaryTreeNode(ElemType value);
void connectTreeNodes(BinaryTreeNode*pParent, BinaryTreeNode*pLeft, BinaryTreeNode*pRight);
void printTreeNode(const BinaryTreeNode*pNode);
void printNode(const BinaryTreeNode*pNode);
void printTree(const BinaryTreeNode*pRoot);
void printTreePreOrder(const BinaryTreeNode*pRoot);
void printTreeInOrder(const BinaryTreeNode*pRoot);
void printTreePostOrder(const BinaryTreeNode*pRoot);
void destroyTree(BinaryTreeNode*pRoot);

BinaryTree.cpp

/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//

#include "BinaryTree.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>

typedef int ElemType;

BinaryTreeNode*createBinaryTreeNode(ElemType value)
{
    BinaryTreeNode*pNode = new BinaryTreeNode();
    pNode->m_nValue = value;
    pNode->m_pLeft = nullptr;
    pNode->m_pRight = nullptr;
    return pNode;
}

void connectTreeNodes(BinaryTreeNode*pParent, BinaryTreeNode*pLeft, BinaryTreeNode*pRight)
{
    if(pParent != nullptr)
    {
        pParent->m_pLeft = pLeft;
        pParent->m_pRight = pRight;
    }
}

void printTreeNode(const BinaryTreeNode*pNode)
{
    if(pNode != nullptr)
    {
        std::cout << "Value of this node is " << pNode->m_nValue << std::endl;

        if(pNode->m_pLeft != nullptr)
        {
            std::cout << "Value of its left child is " << pNode->m_pLeft->m_nValue << std::endl;
        }else{
            std::cout << "left child is nullptr." << std::endl;
        }

        if(pNode->m_pRight != nullptr)
        {
            std::cout << "Value of its right child is " << pNode->m_pRight->m_nValue << std::endl;
        }else{
            std::cout << "right child is nullptr." << std::endl;
        }
    }else{
        std::cout << "this node is nullptr." << std::endl;
    }
}

void printTree(const BinaryTreeNode*pRoot)
{
    printTreeNode(pRoot);

    if(pRoot != nullptr)
    {
        if(pRoot->m_pLeft != nullptr)
            printTree(pRoot->m_pLeft);
        
        if(pRoot->m_pRight != nullptr)
            printTree(pRoot->m_pRight);
    }
}

void printNode(const BinaryTreeNode*pNode)
{
    if(pNode != nullptr)
        std::cout << pNode->m_nValue << " ";
}

void printTreePreOrder(const BinaryTreeNode*pRoot)
{
    printNode(pRoot);

    if(pRoot != nullptr)
    {
        if(pRoot->m_pLeft != nullptr)
            printTreePreOrder(pRoot->m_pLeft);
        
        if(pRoot->m_pRight != nullptr)
            printTreePreOrder(pRoot->m_pRight);
    }
}

void printTreeInOrder(const BinaryTreeNode*pRoot)
{
    if(pRoot != nullptr)
    {
        if(pRoot->m_pLeft != nullptr)
            printTreeInOrder(pRoot->m_pLeft);
    }

    printNode(pRoot);

    if(pRoot != nullptr)
    {
        if(pRoot->m_pRight != nullptr)
            printTreeInOrder(pRoot->m_pRight);
    }
}
void printTreePostOrder(const BinaryTreeNode*pRoot)
{
    if(pRoot != nullptr)
    {
        if(pRoot->m_pLeft != nullptr)
            printTreePostOrder(pRoot->m_pLeft);

        if(pRoot->m_pRight != nullptr)
            printTreePostOrder(pRoot->m_pRight);
    }

    printNode(pRoot);
}
void destroyTree(BinaryTreeNode*pRoot)
{
    if(pRoot != nullptr)
    {
        BinaryTreeNode*pLeft = pRoot->m_pLeft;
        BinaryTreeNode*pRight = pRoot->m_pRight;

        delete pRoot;
        pRoot = nullptr;

        destroyTree(pLeft);
        destroyTree(pRight);

    }
}

constructBinaryTree.cpp

/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//

#include "../utils/BinaryTree.h"
#include <iostream>
#include <exception>
#include <cstdio>
#include <cstdlib>

typedef int ElemType;

using namespace std;

BinaryTreeNode*coonstructCore(ElemType*startPreorder, ElemType*endPreorder, ElemType*startInorder, ElemType*endInorder)
{
    // 前序遍历的第一个节点就是根节点的值
    ElemType rootValue = *startPreorder;
    BinaryTreeNode*root = new BinaryTreeNode();
    root->m_nValue = rootValue;
    root->m_pLeft = NULL;
    root->m_pRight = NULL;

    if(startPreorder == endPreorder)
    {
        if(startInorder == endInorder && *startPreorder == *startInorder)
        {
            // std::cout << "1 " << *startPreorder << std::endl;
            // 找到当前的根节点返回
            return root;
        }else{
            throw ("invalid Input.");
        }
    }

    // 在前序遍历中查找根节点的值
    ElemType*rootInorder = startInorder;
    while(rootInorder <= endInorder && *rootInorder != rootValue)
        ++rootInorder;
    
    if(rootInorder == endInorder && *rootInorder != rootValue)
        throw ("Invalid Input.");
    
    int leftLength = rootInorder - startInorder;
    ElemType*leftPreorderEnd = startPreorder + leftLength;
    if(leftLength > 0)
    {
        // 递归构建左子树
        root->m_pLeft = coonstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1);
    }
    if(leftLength < endPreorder - startPreorder)
    {
        // 递归构建右子树
        root->m_pRight = coonstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);
    }

    return root;
}

BinaryTreeNode*construct(ElemType*preorder, ElemType*inorder, int length)
{
    if(preorder == NULL || inorder == NULL || length == 0)
        return NULL;

    return coonstructCore(preorder, preorder+length-1, inorder, inorder+length-1);
}

void test_createBinaryTree()
{
    BinaryTreeNode*T_1 = createBinaryTreeNode(1);
    BinaryTreeNode*T_2 = createBinaryTreeNode(2);
    BinaryTreeNode*T_3 = createBinaryTreeNode(3);
    BinaryTreeNode*T_4 = createBinaryTreeNode(4);
    BinaryTreeNode*T_5 = createBinaryTreeNode(5);
    BinaryTreeNode*T_6 = createBinaryTreeNode(6);
    BinaryTreeNode*T_7 = createBinaryTreeNode(7);

    connectTreeNodes(T_1, T_2, T_3);
    connectTreeNodes(T_2, T_4, T_5);
    connectTreeNodes(T_3, T_6, T_7);

    printTree(T_1);
    cout << endl;

    destroyTree(T_1);
}

void test_printTree()
{
    BinaryTreeNode*T_1 = createBinaryTreeNode(1);
    BinaryTreeNode*T_2 = createBinaryTreeNode(2);
    BinaryTreeNode*T_3 = createBinaryTreeNode(3);
    BinaryTreeNode*T_4 = createBinaryTreeNode(4);
    BinaryTreeNode*T_5 = createBinaryTreeNode(5);
    BinaryTreeNode*T_6 = createBinaryTreeNode(6);
    BinaryTreeNode*T_7 = createBinaryTreeNode(7);

    connectTreeNodes(T_1, T_2, T_3);
    connectTreeNodes(T_2, T_4, T_5);
    connectTreeNodes(T_3, T_6, T_7);


    cout << "前序遍历" << endl;
    printTreePreOrder(T_1);
    cout << endl;

    cout << "中序遍历" << endl;
    printTreeInOrder(T_1);
    cout << endl;

    cout << "后序遍历" << endl;
    printTreePostOrder(T_1);
    cout << endl;

    destroyTree(T_1);
}

void test_constructTree(ElemType*preOrder, ElemType*inOrder, int length)
{
    BinaryTreeNode*T = construct(preOrder, inOrder, length);
    cout << "前序序列" << endl;
    printTreePreOrder(T);
    cout << endl << "中序序列" << endl;
    printTreeInOrder(T);
    cout << endl << "后序序列" << endl;
    printTreePostOrder(T);
    cout << endl;
}

void test_constructTree_1()
{
    cout << "不完全二叉树测试" << endl;
    ElemType preOrder[] = {1, 2, 4, 7, 3, 5, 6, 8};
    ElemType inOrder[]  = {4, 7, 2, 1, 5, 3, 8, 6};
    test_constructTree(preOrder, inOrder, 8);
}

void test_constructTree_2()
{
    cout << "完全二叉树测试" << endl;
    ElemType preOrder[] = {1, 2, 4, 8, 9, 5, 10, 11, 3, 6, 12, 13, 7, 14, 15};
    ElemType inOrder[]  = {8, 4, 9, 2, 10, 5, 11, 1, 12, 6, 13, 3, 14, 7, 15};
    test_constructTree(preOrder, inOrder, 15);
}

void test_constructTree_3()
{
    cout << "只有左子树" << endl;
    ElemType preOrder[] = {1, 2, 3, 4, 5, 6, 7};
    ElemType inOrder[]  = {7, 6, 5, 4, 3, 2, 1};
    test_constructTree(preOrder, inOrder, 7);
}

void test_constructTree_4()
{
    cout << "只有右子树" << endl;
    ElemType preOrder[] = {1, 2, 3, 4, 5, 6, 7};
    ElemType inOrder[]  = {1, 2, 3, 4, 5, 6, 7};
    test_constructTree(preOrder, inOrder, 7);
}

void test_constructTree_5()
{
    cout << "不匹配测试" << endl;
    ElemType preOrder[] = {1, 2, 3, 4, 5, 6, 7};
    ElemType inOrder[]  = {1, 2, 3, 4, 7, 6, 0};
    test_constructTree(preOrder, inOrder, 7);
}

void test_construct()
{
    test_constructTree_1();
    test_constructTree_2();
    test_constructTree_3();
    test_constructTree_4();
    test_constructTree_5();
    
}

int main(int argc, char**argv)
{

    test_createBinaryTree();
    test_printTree();
    test_construct();

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值