通过已知遍历建二叉树
唯一确定二叉树三种:
中序遍历 + 层序遍历
中序遍历 + 前序遍历
中序遍历 + 后序遍历
1:中序遍历 + 层序遍历建树:
具体思路:
先遍历层序序列,选取每一个在中序遍历的位置,进行build,
但由于一开始无树,建根节点
当存在根节点后,此时层序遍历的结点就指向下一个,记为 k (将要插入的)
再次遍历中序序列,直到查找到与root的值相同的位置,记为 u (已经存在的)
如果 k < u , 向左子树插入, 反之,向右子树插入
int level[100],mid[100];
struct node{
int data;
node *left;
node *right;
};
void build(struct node* &root, int data, int k){
if(root == NULL){
root = new node;
root->data = data;
root->left = NULL;
root->right = NULL;
return;
}
int u;
for(u=1; u<=n; u++){
if(mid[u] == root->data) break;
}
if(k<u) build(root->left, data, k);
else build(root->right, data, k);
}
int main(){
struct node *root;
cin>>n;
for(int i=1;i<=n;i++) cin>>mid[i];
for(int i=1;i<=n;i++) cin>>layer[i];
root = NULL;
for(int i=1;i<=n;i++){
int k;
for(k=1;k<=n;k++){
if(mid[k] == layer[i]) break;
}
build(root, layer[i], k);
}
}
2: 中序遍历 + 前序遍历建树:
方法:想办法分出左右子树,对左右树进行递归构建 (下同)
#include <bits/stdc++.h>
using namespace std;
int n,num=1;
int pre[100],mid[100];
struct node{
int data;
node *left;
node *right;
};
struct node* build(int preL, int preR, int midL, int midR){
if(preL > preR){
return NULL;
}
node *root = new node;
root->data = pre[preL]; // 后序遍历的最后一个
root->left = NULL;
root->right = NULL;
int t;
for(t = midL; t<=midR ; t++){
if(mid[t] == pre[preL])
break;
}
int numleft = t-midL;
root->left = build(preL+1, preL+numleft, midL, t-1);
root->right = build(preL+numleft+1, preR, t+1 , midR);
return root;
}
void dfs(struct node *root){
if(root->left) dfs(root->left);
if(root->right) dfs(root->right);
printf("%d ",root->data);
}
int main(){
struct node * root;
cin>>n;
for(int i=1;i<=n;i++) cin>>pre[i];
for(int i=1;i<=n;i++) cin>>mid[i];
root = build(1,n,1,n);
dfs(root); //用后序遍历测试
return 0;
}
/*
样例:
7
1 2 4 5 3 6 7
4 2 5 1 6 3 7
则正确的后序遍历:
4 5 2 6 7 3 1
*/
3:中序遍历 + 后序遍历建树:
int pro[100],mid[100];
struct node{
int data;
node *left;
node *right;
};
struct node* build(int midL, int midR, int proL, int proR){
if(midL > midR || proL > proR){
return NULL;
}
struct node *root;
root = new node;
root->data = pro[proR];
root->lchild = root->rchild = NULL;
int k,mark;
for(k=midL; k<=midR;k++){
if(mid[k] == pro[proR]) break;
}
mark = k - midL;
root->lchild = build(midL, midL+mark-1, proL, proL+mark-1);
root->rchild = build(midL+mark+1, midR, proL+mark, proR-1);
return root;
}
int main(){
struct node * root;
cin>>n;
for(int i=1;i<=n;i++) cin>>pro[i];
for(int i=1;i<=n;i++) cin>>mid[i];
root = build(1,n,1,n);
}