这是一个数据结构关于树的经典问题。正好今天看《算法笔记》看到了。
样例树:
前:ABDECF
中:DBEACF
书上给的代码是这样的(经过了我的微小改装,数据用的是书上的):
#include<bits/stdc++.h>
using namespace std;
struct node{//每个节点的数据
char data;
node* lchild;
node* rchild;
};
int preL=0,preR=5,inL=0,inR=5;
char in[] = {'D','B','E','A','C','F'};//中序数列
char pre[] = {'A','B','D','E','C','F'};//前序数列
//当前先序序列区间为[preL,preR],中序序列区间为[inL,inR],返回根节点地址
node* create(int preL,int preR,int inL,int inR){
if(preL>preR) return NULL;//先序序列长度小于0时,直接返回
node* root = new node;//新建一个结点,用来存放当前二叉树的根结点//!!这里也容易写错因为要新建一颗树,根是node*类型
root->data = pre[preL];//新结点的数据域为根结点的值
int k;
for(k = inL;k<=inR;k++){//!!这里容易写错,记得深刻理解思路,这里是去中序序列里面找出来原数根的位置,求出左子树的结点数
if(in[k] == pre[preL]){//在中序序列中找到in[k] == pre[L]的结点
break;
}
}
int numLeft = k - inL;//左子树的结点个数
printf("preL:%d preR:%d inL:%d inR:%d\n加入了%c元素 k:%d numLeft:%d\n-----------\n",preL,preR,inL,inR,root->data,k,numLeft);//打印各种变量
//左子树的先序区间为[preL+1,preL+numLeft],中序区间为[inL,k-1]
//返回左子树根结点地址,赋值给root的左指针
root->lchild = create(preL+1,preL+numLeft,inL,k-1);
//右子树的先序区间为[preL+numLeft+1,preR],中序区间为[k+1,inR]
//返回右子树根结点地址,赋值给root的右指针
root->rchild = create(preL+numLeft+1,preR,k+1,inR);
}
int main(){
create(preL,preR,inL,inR);
}
会输出建树结果:
preL:0 preR:5 inL:0 inR:5
加入了A元素 k:3 numLeft:3
-----------
preL:1 preR:3 inL:0 inR:2
加入了B元素 k:1 numLeft:1
-----------
preL:2 preR:2 inL:0 inR:0
加入了D元素 k:0 numLeft:0
-----------
preL:3 preR:3 inL:2 inR:2
加入了E元素 k:2 numLeft:0
-----------
preL:4 preR:5 inL:4 inR:5
加入了C元素 k:4 numLeft:0
-----------
preL:5 preR:5 inL:5 inR:5
加入了F元素 k:5 numLeft:0
-----------
核心思想就是
中序用来辅助找出来根结点的左子树和右子树的节点个数之后就可以递归调用,用前序来建树。
给出后序和中序序列也可以构建一颗二叉树,做法是一样的。
当前前序数列:
ABDECF
当前中序序列:
ABDECF
preL:0 preR:5 inL:0 inR:5
加入了A元素 k:3 numLeft:3
-----------
当前前序数列:
BDE
当前中序序列:
ABD
preL:1 preR:3 inL:0 inR:2
加入了B元素 k:1 numLeft:1
-----------
当前前序数列:
D
当前中序序列:
A
preL:2 preR:2 inL:0 inR:0
加入了D元素 k:0 numLeft:0
-----------
当前前序数列:
当前中序序列:
当前前序数列:
当前中序序列:
当前前序数列:
E
当前中序序列:
D
preL:3 preR:3 inL:2 inR:2
加入了E元素 k:2 numLeft:0
-----------
当前前序数列:
当前中序序列:
当前前序数列:
当前中序序列:
当前前序数列:
CF
当前中序序列:
CF
preL:4 preR:5 inL:4 inR:5
加入了C元素 k:4 numLeft:0
-----------
当前前序数列:
当前中序序列:
当前前序数列:
F
当前中序序列:
F
preL:5 preR:5 inL:5 inR:5
加入了F元素 k:5 numLeft:0
-----------
当前前序数列:
当前中序序列:
当前前序数列:
当前中序序列: