先序+中序,后序+中序创建二叉树的关键在于,使用分治思想,先在先序或后序中找到当前子树的根节点,并在中序中找到位置,来划分左右子树区间
// pre与in不仅表示先序中序序列,同时也表示当前子串的开头,n为当前子串长度
Node* creat_pre_in(char *pre, char *in, int n){ // 先序加中序
Node *s; char *p; int k;
if (n <= 0)
return NULL;
s = new Node(); // 创建根节点
s->val = *pre; // 先序第一个节点为当前根节点
for (p = in; p < in+n; p++) // 找到根节点在中序中位置
if (*p == *pre)
break;
k = p-in; // k表示左串长度
// 划分左右子串,递归创建左右子树
s->lchild = creat_pre_in(pre+1, in, k);
s->rchild = creat_pre_in(pre+k+1, in+k+1, n-k-1);
return s;
}
先序+后续与其类似,但有所不同的是,选择先序的第一个字符作为根节点后,需要选择先序第二个字符,在后序中寻找,来划分区间
因此当区间只有一个节点时,需要直接返回当前节点,无节点时仍需返回空指针
// 与前面不同的是,当只有一个节点时,无法找到pre+1位置,此时直接返回节点
Node* creat_pre_post(char *pre, char *post, int n){ // 先序+后序
Node *s; char *p; int k;
if (n <= 0)
return NULL;
s = new Node();
s->val = *pre;
if (n == 1)
return s;
for (p = post; p < post+n; p ++)
if (*p == *(pre+1))
break;
k = p-post+1;
s -> lchild = creat_pre_post(pre+1, post, k);
s -> rchild = creat_pre_post(pre+k+1, post+k, n-k-1);
return s;
}
完整代码:
# include <bits/stdc++.h>
using namespace std;
const int N = 1003;
struct Node{
char val;
Node *lchild, *rchild;
};
// pre与in不仅表示先序中序序列,同时也表示当前子串的开头,n为当前子串长度
Node* creat_pre_in(char *pre, char *in, int n){ // 先序加中序
Node *s; char *p; int k;
if (n <= 0)
return NULL;
s = new Node(); // 创建根节点
s->val = *pre; // 先序第一个节点为当前根节点
for (p = in; p < in+n; p++) // 找到根节点在中序中位置
if (*p == *pre)
break;
k = p-in; // k表示左串长度
// 划分左右子串,递归创建左右子树
s->lchild = creat_pre_in(pre+1, in, k);
s->rchild = creat_pre_in(pre+k+1, in+k+1, n-k-1);
return s;
}
Node* creat_in_post(char *post, char *in, int n){ // 后序加中序
Node *s; char r, *p; int k;
if (n <= 0)
return NULL;
s = new Node();
r = *(post+n-1);
s->val = r;
for(p = in; p < in+n; p ++)
if (*p == r)
break;
k = p-in;
s -> lchild = creat_in_post(post, in, k);
s -> rchild = creat_in_post(post+k, in+k+1, n-k-1);
return s;
}
// 与前面不同的是,当只有一个节点时,无法找到pre+1位置,此时直接返回节点
Node* creat_pre_post(char *pre, char *post, int n){ // 先序加后序
Node *s; char *p; int k;
if (n <= 0)
return NULL;
s = new Node();
s->val = *pre;
if (n == 1)
return s;
for (p = post; p < post+n; p ++)
if (*p == *(pre+1))
break;
k = p-post+1;
s -> lchild = creat_pre_post(pre+1, post, k);
s -> rchild = creat_pre_post(pre+k+1, post+k, n-k-1);
return s;
}
void bfs_level(Node *T){ // 层序遍历
queue<Node*> q;
q.push(T);
while (!q.empty()){
Node *p = q.front(); q.pop();
cout << p->val << " ";
if (p->lchild) q.push(p->lchild);
if (p->rchild) q.push(p->rchild);
}
puts("");
}
int main(){
int n;
char a[N], b[N];
cin >> n;
cin >> a;
cin >> b;
Node *T = creat_pre_post(a, b, n);
bfs_level(T);
return 0;
}
/*
先后
7
ABDGECF
GDEBFCA
前中
7
ABDGCEF
DGBAECF
后中
7
GDBEFCA
DGBAECF
*/