中序遍历和层次遍历构造二叉树

/*
    题目:层次遍历和中序遍历构建二叉树
    算法思想:InOrder, LevelOrder 分别存储中序序列和层变遍历序列,用cnt1记录层次遍历序列插入结点的下标,[low, high]为插入结点在中序序列的范围,插入LevelOrder[cnt1]
    找到LevelOrder[cnt1](层次遍历序列结点)在[low, high](中序序列)具体位置 mid
    若 mid > low 则根据[low, mid - 1]和LevelOrder[cnt1 + 1] 继续插入
    若 mid < high 则根据 [mid + 1, high] 和 LevelOrder[cnt1 + 2](存在左兄弟,左兄弟占用LevelOrder[cnt1 + 1); 
    或LevelOrder[cnt1 + 1](不存在左兄弟)继续插入 
*/ 
#include
#include
using namespace std;

typedef struct BNode        //二叉树结点 
{
    int data;
    struct BNode *lchild, *rchild;
}BNode;

typedef struct infor        //插入时需要的信息  infor(information)
{
    int low, high;            //插入结点在中序队列中的位置范围 
    int flag;                //1 插入双亲结点的右结点, 0 左结点 
    BNode *parent;            //插入结点的双亲结点 
}infor;

int InOrder[100];
int LevelOrder[100];

void PreOrder(BNode *T)        //三种遍历方式,用于验证正误 
{
    if (T == NULL)
        return;
    printf("%d ", T->data);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
}
void InOrder2(BNode *T)
{
    if (T == NULL)
        return;
    InOrder2(T->lchild);
    printf("%d ", T->data);
    InOrder2(T->rchild);    

void PostOrder(BNode *T)
{
    if (T == NULL)
        return;
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    printf("%d ", T->data);
}
int main()
{
    int n, cnt1;        //树的结点个数
    queue q;
    BNode *T;
    while(scanf("%d", &n) == 1)
    {
        while(!q.empty())    q.pop();    //清空队列 
//        中序遍历序列
        for (int i = 0; i < n; i++) 
        {
            scanf("%d", &InOrder[i]);
        }
//        层次遍历序列 
        for (int i = 0; i < n; i++)    
        {
            scanf("%d", &LevelOrder[i]);
        }
//        不适用递归    适用层次遍历的方法进行
        cnt1 = 0;                                //层次遍历序列的下标 
        BNode *T = new BNode;                    //定义一个没有数据的根结点 
        
        infor temp;
        temp.parent = T;
        temp.flag = 0;                            //插入左结点 
        temp.low = 0;                            //存放待插入结点所在的中序范围 
        temp.high = n - 1;
        q.push(temp);
        while(!q.empty())
        {
            temp = q.front();
            q.pop();
            BNode *t = temp.parent;
            
//            printf("插入数%d---范围%d---%d\n", LevelOrder[cnt1], temp.low, temp.high);
//            插入 
            if (temp.flag == 0)        //在双亲结点的左子树插入 
            {
                
                t->lchild = new BNode;             
                t->lchild->data = LevelOrder[cnt1]; 
                t->lchild->lchild = t->lchild->rchild = NULL;
                t = t->lchild;                    //用于给后边buf入队提供双亲结点 
            }     
            else                    //右子树 
            {
                t->rchild = new BNode;
                t->rchild->data = LevelOrder[cnt1];
                t->rchild->lchild = t->rchild->rchild = NULL;
                t = t->rchild;
            }
//            查找LevelOrder[cnt1]在中序遍历序列中的位置
            int mid;
            for (mid = temp.low; mid <= temp.high; mid++)
            {
                if (InOrder[mid] == LevelOrder[cnt1])
                    break;    
            }
//            printf("%d\n", mid); 
//            通过mid的位置,判断
            if (mid > temp.low)
            {
                infor buf = temp;        //暂存temp值 
                buf.high = mid - 1;
                buf.parent = t;
                buf.flag = 0;
                q.push(buf);    
            } 
            if (mid < temp.high)
            {
                infor buf = temp; 
                buf.low = mid + 1;
                buf.parent = t;
                buf.flag = 1;
                q.push(buf);
            }
            cnt1++;
        }
        PreOrder(T->lchild);         
        printf("\n");
        InOrder2(T->lchild);
        printf("\n");
        PostOrder(T->lchild);    
    } 
     return 0;
}
 

你可能感兴趣的:(中序遍历和层次遍历构造二叉树)