根据先序序列和中序,后序和中序序列创建二叉树


思考:如何才能确定一棵树?

结论:    通过中序遍历和先序遍历可以确定一个树
                通过中序遍历和后续遍历可以确定一个树

                通过先序遍历和后序遍历确定不了一个树。

算法实现:

(一)先序和中序重建二叉树,按层次遍历输出

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

struct node
{
    char data;
    node *lchild, *rchild, *mparent;
};

node* tmpParent = nullptr;
node* CreateBT1(char* pre, char* in, int n)
{
    node* b;
    char* p;
    int k;

    if (n <= 0 || pre == nullptr || in==nullptr)     //代码鲁棒性,细节必须注意
        return nullptr;

    b = (node*)malloc(sizeof(node));
    b->data = *pre;
    b->mparent = tmpParent;

    for (p = in; p < in + n; ++p)
        if (*p == *pre)
            break;

    k = p - in;
    b->lchild = CreateBT1(pre + 1, in, k);
    b->rchild = CreateBT1(pre + k + 1, p + 1, n - k - 1);
    
    return b;
}

int first_flag = 0;

void layerOrder(node * root)
{
    queue<node *> ans;
    ans.push(root);
    while (!ans.empty())
    {
        node * tmp = ans.front();
        ans.pop();
        if (first_flag != 0)
        {
            cout << " ";
        }
        cout << tmp->data;
        first_flag = 1;
        if (tmp->lchild != NULL) ans.push(tmp->lchild);
        if (tmp->rchild != NULL) ans.push(tmp->rchild);
    }
}

void DispBTNode(node* b)
{
    if (b != nullptr)
    {
        printf("%c ", b->data);

        if (b->lchild != NULL || b->rchild != NULL)
        {
            DispBTNode(b->lchild);
            //printf(",");

            if (b->rchild!=NULL)
                DispBTNode(b->rchild);
            //printf(",");

        }
    }
}

int main()
{
    /*for (int i = 0; i<n; i++)
    {
        cin >> post[i];
    }
    for (int i = 0; i<n; i++)
    {
        cin >> in[i];
    }*/
    char str1[40] = { 0 };  char str2[40] = { 0 };
    scanf("%s", str1);scanf("%s", str2);

    int n = strlen(str1);
    node * root;
    root = CreateBT1((char*)str1, (char*)str2, n);

    printf("按中序序列将新建的二叉树输出\n");
    DispBTNode(root);
    
    printf("按后序序列将新建的二叉树输出\n");
    layerOrder(root);
    return 0;
}


(二)根据后序序列和中序序列重建树,按层次遍历输出

       关于怎样由后序和中序重建二叉树原理读者可以自己查书,本博文仅供作者自己笔记之用

//代码:

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;

struct node
{
    char data;
    node *lchild, *rchild;
};

node* CreateBT2(char* post/*指向后序序列开头的指针*/, char* in/*指向中序序列开头的指针*/, int n)
{

    char r, *p;

    int k;
  
    if (n <= 0 || post== nullptr || in==nullptr)     //代码鲁棒性,细节必须注意
        return nullptr;

    r = *(post + n - 1);
    node* b = (node*)malloc(sizeof(node));
    b->data = r;      //我们要创建的树根节点建立好了

    for (p = in; p < in + n; ++p)
        if (*p == r) break;

    k = p - in;      //k是左子树节点数

    b->lchild = CreateBT2(post, in, k);              //这两个语句最关键
    b->rchild = CreateBT2(post + k, p + 1, n - k - 1);

    return b;
}


/****************打印各节点***********************/
int first_flag = 0;
void layerOrder(node * root)
{
    queue<node *> ans;
    ans.push(root);
    while (!ans.empty())
    {
        node * tmp = ans.front();
        ans.pop();
        if (first_flag != 0)
        {
            cout << " ";
        }
        cout << tmp->data;
        first_flag = 1;
        if (tmp->lchild != NULL) ans.push(tmp->lchild);
        if (tmp->rchild != NULL) ans.push(tmp->rchild);
    }
}

int main()
{
    int n;
    cin >> n;

    char str1[40] = { 0 };  char str2[40] = { 0 };
    scanf("%s", str1); scanf("%s", str2);


    node * root = CreateBT2(str1, str2, n);

    layerOrder(root);
    return 0;
}


转载请私信博主征得同意,并注明出处:https://blog.csdn.net/qq_34793133/article/details/80582358





猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/80582358