前言
关于二叉树先、中、后遍历序列给一个中序序列以及其他一个就能够推出另一个序列,而如果单单只有先序与后序序列只能得到某两个结点的父子关系而不能确定一个唯一的二叉树。
算法
主要流程就是搜索,每次通过先序确定根节点,然后根据中序序列确定两个子树的规模,递归下去。
复杂度分析
在平均情况: T ( n ) = 2 ∗ T ( n / 2 ) + n T(n)=2*T(n/2)+n T(n)=2∗T(n/2)+n
得:复杂度: O ( n ∗ l o g 2 n ) O(n*log2^n) O(n∗log2n)
实现
先、中序列求后序序列:
#include <bits/stdc++.h>
using namespace std;
#define Elem char
struct BiTree {
Elem elem;
BiTree *lson, *rson;
BiTree(Elem ch):elem(ch),lson(NULL),rson(NULL){}
~BiTree(){}
};
//根结点 先序序列 中序序列 序列长度
void dfs (BiTree* &rt, Elem A[], Elem B[], int len) {
if (len <= 0) //null
return ;
if (len == 1) { //leaf
rt = new BiTree(A[0]);
return ;
}
int index = 0; //子树根在中序序列中的位置
for (int i = 0; i < len; i++)
if (B[i] == A[0]) {
index = i;
break;
}
rt = new BiTree(A[0]);
dfs(rt->lson, A+1, B, index);
dfs(rt->rson, A+index+1, B+index+1, len-index-1);
}
void f(BiTree *rt) {
if (rt) {
f(rt->lson);
f(rt->rson);
printf("%c", rt->elem);
}
}
void mem_del(BiTree *rt) {
if (rt) {
mem_del(rt->lson);
mem_del(rt->rson);
delete rt;
}
}
int main() {
Elem A[] = "ABCDEF";
Elem B[] = "CBAEDF";
BiTree *rt = NULL;
int len = 6;
dfs(rt, A, B, len);
f(rt);
mem_del(rt);
printf("\n");
return 0;
}
由后、中序列求先序也同理:
#include <bits/stdc++.h>
using namespace std;
#define Elem char
struct BiTree {
Elem elem;
BiTree *lson, *rson;
BiTree(Elem ch):elem(ch),lson(NULL),rson(NULL){}
~BiTree(){}
};
//根结点 后序序列 中序序列 序列长度
void dfs (BiTree* &rt, Elem A[], Elem B[], int len) {
if (len <= 0) //null
return ;
if (len == 1) { //leaf
rt = new BiTree(A[0]);
return ;
}
int index = 0; //子树根在中序序列中的位置
for (int i = 0; i < len; i++)
if (B[i] == A[len-1]) {
index = i;
break;
}
rt = new BiTree(A[len-1]);
dfs(rt->lson, A, B, index);
dfs(rt->rson, A+index, B+index+1, len-index-1);
}
void f(BiTree *rt) {
if (rt) {
printf("%c", rt->elem);
f(rt->lson);
f(rt->rson);
}
}
void mem_del(BiTree *rt) {
if (rt) {
mem_del(rt->lson);
mem_del(rt->rson);
delete rt;
}
}
int main() {
Elem A[] = "DABEC";
Elem B[] = "DEBAC";
BiTree *rt = NULL;
int len = strlen(A);
dfs(rt, A, B, len);
f(rt);
mem_del(rt);
printf("\n");
return 0;
}