通过先序与中序遍历确定二叉树

//设 T 是一棵具有 n 个节点的二叉树,若给定二叉树 T 的先序序列和中序序列,并假设 T 的先序序列和中序序列分别放在数组 PreOrder[1..n]和 InOrder[1..n ]中,设计一个构造二叉树 T 的链式存储结构的算法。

#include <iostream>
#include <stack>
#include <queue>
#include <string>
using namespace std;

#define TElemType int

#define max 1024

typedef struct BiTNode{
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//设 T 的先序序列和中序序列分别放在数组 PreOrder[1..n]和 InOrder[1..n ]中,根据先序遍 历的特点可知,PreOrder[1]为根节点,设中序序列中 InOrder[i]=PreOrder[1],则在 InOrder[i] 的左面的 InOrder[1..i-1]应为二叉树的左子树,而 InOrder[i+1..n]为根的右子树。相对应的是, 在先序序列中根的左子树应为 PreOrder[2..i],而右子树为 PreOrder[i+1..n]。而左子树的根为 PreOrder[2],右子树的根为 PreOrder[i+1]。依次递归,用同样的方法可以确定子树的左子树 和右子树,从而逐步确定整个二叉树

//递归
//              左子树             右子树
//先序      i1+1 -> i1+i-i2       i1+i+1-i2->j1
//后序        i2 -> i-1            i+1 -> j2

//这里因为T在函数内部还会改变,所以需要加个引用(也可以理解为二重指针)
void CreateTree(BiTree &T, TElemType preorder[], int i1, int j1, TElemType inorder[], int i2, int j2){
    int i=i2;   //先建立i,用于后续定位中序序列中的局部根结点位置
    if(i1<=j1){
        T=(BiTree) malloc(sizeof(BiTNode));
        T->data=preorder[i1];   //先序遍历的第一个结点为根结点
//        cout<<"add "<<T<<endl;
        T->lchild=NULL;
        T->rchild=NULL;
        while(inorder[i]!=preorder[i1])
            i++;    //找到根结点在中序遍历中的位置,以此左为左子树,右为右子树
//        cout<<"tag"<<endl;
        CreateTree(T->lchild, preorder, i1+1, i1+i-i2, inorder, i2, i-1);   //遍历左右子树
        CreateTree(T->rchild, preorder, i1+i+1-i2, j1, inorder, i+1, j2);
    }
    else
        T=NULL;
}

int main(){
    int preorder[7]={0,1,2,4,5,3,6};
    int inorder[7]={0,4,2,5,1,6,3};
    BiTree S=(BiTree) malloc(sizeof(BiTNode));
    CreateTree(S, preorder, 1, 6, inorder, 1, 6);
    queue<BiTree> q;
    q.push(S);
    cout<<"以层次遍历访问此树"<<endl;
    while(!q.empty()){
        BiTree t=q.front();
        q.pop();
        cout<<t->data<<endl;
        if(t->lchild!=NULL)
            q.push(t->lchild);
        if(t->rchild)
            q.push(t->rchild);
    }
}

 

posted @ 2019-09-11 19:55  图袋鼠  阅读(1286)  评论(0编辑  收藏  举报