数据结构——根据前序遍历和中序遍历还原二叉树

#include <iostream>
/*
给定了前序遍历和中序遍历,还原一刻二叉树
*/
using namespace std;


//定义一颗二叉树的节点
struct binaryNode
{
    int nodeValue;
    binaryNode* leftChild;
    binaryNode* rightChild;
};
void postTraverse(binaryNode *p);
binaryNode* constructTree(int* preOrder,int* inOrder, int length);
binaryNode* constructCore(int* startPreOrder,int* endPreOrder,int* startInOreder, int* endInOrder);
int main()
{
    int preOrder[] ={1,2,4,7,3,5,6,8};
    int inOrder[] ={4,7,2,1,5,3,8,6};

    binaryNode* root = constructTree(&preOrder[0],&inOrder[0],8);
    postTraverse(root);
    cout<<endl;
    return 0;
}

          //还原二叉树子函数
binaryNode* constructTree(int* preOrder,int* inOrder, int length)
{
          //1.判断输入的值是否合法
    if(preOrder==NULL || inOrder==NULL || length<=0){
        return NULL;
    }else{
       return constructCore(preOrder,preOrder+length-1,inOrder,inOrder+length-1);
    }
}
binaryNode* constructCore(int* startPreOrder,int* endPreOrder,int* startInOrder, int* endInOrder)
{
          //2.找到前序遍历中的根节点并创建一个节点保存节点值
    binaryNode * root = new binaryNode();
    root->nodeValue = startPreOrder[0];
    root->leftChild = NULL;
    root->rightChild = NULL;

          //3.判断是否找完了此次中序遍历,若是找完了,则返回 root
    if(startInOrder==endInOrder && *startInOrder== *endInOrder)
    {
        return root;
    }

          //4.根据此根节点的值在中序遍历中找此次节点的位置
    int* rootInOrder=startInOrder;
    while( *startPreOrder != *rootInOrder){
        rootInOrder++;
    }
          //6.根据此根节点在中序遍历中的位置,递归还原左子树
    int leftlength = rootInOrder - startInOrder;
    if(leftlength>0)
    {
        root->leftChild = constructCore(startPreOrder+1,startPreOrder+leftlength,startInOrder,startInOrder+leftlength-1);
    }
    //此处千万不要错写成 else if 因为若是这样,判断满足上面的递归条件,则进入递归还原左子树,当左子树完全被还原后,再调回这个点的时候,就不会继续执行 else if 语句了,因为上面的条件已经满足,所以右子树将没办法还原了
    if(leftlength + startInOrder < endInOrder)      //左子树长度加上中序的起始位置后若仍然小于整个中序长度则说明该节点还存在右子树,所以继续递归还原右子树
    {//7.根据此根节点在中序遍历中的位置,递归还原右子树
        root->rightChild = constructCore(startPreOrder+leftlength+1,endPreOrder,startInOrder+leftlength+1,endInOrder);
    }
    return root;
}
//后序遍历二叉树
void postTraverse(binaryNode *p)
{
    if(NULL != p->leftChild)
        postTraverse(p->leftChild);
    if(NULL != p->rightChild)
        postTraverse(p->rightChild);
    if(NULL != p)
        cout<<p->nodeValue<<" ";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值