chapter §11 二叉树的建立(先序+中序和后序+中序建立二叉树)

一、先序序列加中序序列构造二叉树

从左到右遍历先序序列,访问到的当前元素即为根结点的值,每遍历到一个元素,从左至右遍历中序序列,直到找到中序序列中与之对应的值,记录位置pos,将中序序列一分为二,左边即为左子树的序列,右边为右子树序列。然后据此计算左子树结点个数,即用pos减去中序序列起始位置,从而得到先序序列中以当前结点为根的左子树序列和右子树序列的起始和结束位置。最后对两个子序列继续如上递归操作,直到子树序列长度为0时停止。

二、图示

在这里插入图片描述

三、代码实现

#include <iostream>

using namespace std;
typedef struct BiTNode {
    char data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
} BiTNode, *BiTree;

string PreOrder; //保存先序序列
string InOrder;//保存中序序列
string PostOrder;//保存后序序列
//preleft先序序列的起始位置,preRight先序序列的终止位置,inLeft中序序列的起始位置,inRight中序序列的终止位置
BiTree CreateBiTree_PI(int preLeft, int preRight, int inLeft, int inRight) {
    if (preLeft <= preRight) { //先序序列长度至少为1,即对应子树至少有一个结点
        BiTree T = (BiTNode *) malloc(sizeof(BiTNode));//创建根结点
        T->data = PreOrder[preLeft];//赋值,即为先序序列的第一个元素
        int pos;//记录当前元素在中序序列中的位置
        for (pos = inLeft; pos <= inRight; ++pos) {//求pos
            if (InOrder[pos] == PreOrder[preLeft])
                break;
        }
        int LeftTreeNum = pos - inLeft;//统计左子树结点个数
        T->lchild = CreateBiTree_PI(preLeft + 1, preLeft + LeftTreeNum, inLeft, pos - 1);//递归构造左子树
        T->rchild = CreateBiTree_PI(preLeft + LeftTreeNum + 1, preRight, pos + 1, inRight);//递归构造右子树
        return T;
    } else return NULL;
}
void PreOrderTraverse(BiTree T) { //先序遍历
    if (T != NULL) {
        cout << T->data << " "; //访问根结点
        PreOrderTraverse(T->lchild);//访问左子树
        PreOrderTraverse(T->rchild);//访问右子树
    }

}

void InOrderTraverse(BiTree T) { //中序遍历
    if (T != NULL) {
        InOrderTraverse(T->lchild);//访问左子树
        cout << T->data << " "; //访问根结点
        InOrderTraverse(T->rchild);//访问右子树
    }
}

void PostOrderTraverse(BiTree T) { //后序遍历
    if (T != NULL) {
        PostOrderTraverse(T->lchild);//访问左子树
        PostOrderTraverse(T->rchild);//访问右子树
        cout << T->data << " "; //访问根结点
    }

}

int main() {
    PreOrder = "ABDECFG";
    InOrder = "DBEAFCG";
    PostOrder = "DEBFGCA";
    BiTree T = CreateBiTree_PI(0, 6, 0, 6);
	cout << "先序遍历序列为:";
    PreOrderTraverse(T);
    cout << endl;
    cout << "中序遍历序列为:";
    InOrderTraverse(T);
    cout << endl;
    cout << "后序遍历序列为:";
    PostOrderTraverse(T);
    return 0;
}

在这里插入图片描述

四、后序序列加中序序列构造二叉树

与上面类似,只不过对后序序列,应从右往左遍历,同样访问到的当前元素即为根结点的值,每遍历到一个元素,从左至右遍历中序序列,直到找到中序序列中与之对应的值,将中序序列一分为二,左边即为左子树的序列,右边为右子树序列,计算左子树结点个数,得到先序序列中以当前结点为根左子树序列和右子树序列。在对两个子序列继续如上操作,直到子树序列长度为0时停止。

#include <iostream>

using namespace std;
typedef struct BiTNode {
    char data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
} BiTNode, *BiTree;

string PostOrder; //保存后序序列
string InOrder;//保存中序序列
string PostOrder;//保存后序序列
//postleft为后序序列的起始位置,postRight后序序列的终止位置,inLeft中序序列的起始位置,inRight中序序列的终止位置
BiTree CreateBiTree_HI(int postLeft, int postRight, int inLeft, int inRight) {
    if (postLeft <= postRight) {//后序序列长度至少为1,即对应子树至少有一个结点
        BiTree T = (BiTNode *) malloc(sizeof(BiTNode));
        T->data = PostOrder[postRight];
        int pos;
        for (pos = inLeft; pos <= inRight; ++pos) {
            if (InOrder[pos] == PostOrder[postRight])
                break;
        }
        int LeftTreeNum = pos - inLeft;//计算左子树结点个数
        //后序子树序列依旧从左往右,和中序序列相对应
        T->lchild = CreateBiTree_HI(postLeft, postLeft + LeftTreeNum - 1, inLeft, pos - 1);//递归构造左子树
        T->rchild = CreateBiTree_HI(postLeft + LeftTreeNum, postRight - 1, pos + 1, inRight);//递归构造右子树
        return T;
    } else return NULL;
}
void PreOrderTraverse(BiTree T) { //先序遍历
    if (T != NULL) {
        cout << T->data << " "; //访问根结点
        PreOrderTraverse(T->lchild);//访问左子树
        PreOrderTraverse(T->rchild);//访问右子树
    }

}

void InOrderTraverse(BiTree T) { //中序遍历
    if (T != NULL) {
        InOrderTraverse(T->lchild);//访问左子树
        cout << T->data << " "; //访问根结点
        InOrderTraverse(T->rchild);//访问右子树
    }
}

void PostOrderTraverse(BiTree T) { //后序遍历
    if (T != NULL) {
        PostOrderTraverse(T->lchild);//访问左子树
        PostOrderTraverse(T->rchild);//访问右子树
        cout << T->data << " "; //访问根结点
    }

}

int main() {
    PreOrder = "ABDECFG";
    InOrder = "DBEAFCG";
    PostOrder = "DEBFGCA";
    BiTree T = CreateBiTree_HI(0, 6, 0, 6);
	cout << "先序遍历序列为:";
    PreOrderTraverse(T);
    cout << endl;
    cout << "中序遍历序列为:";
    InOrderTraverse(T);
    cout << endl;
    cout << "后序遍历序列为:";
    PostOrderTraverse(T);
    return 0;
}

在这里插入图片描述

典型实例

https://blog.csdn.net/qq_43643944/article/details/117484489

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Missヾaurora

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值