先序遍历和中序遍历构建二叉树详解
/*
先序 + 中序 = 二叉树
*/
#include<iostream>
#include<stdio.h>
using namespace std;
typedef struct BTreeNode {
int data;
BTreeNode *Lchild, *Rchild;
}Bnode, *ptr;
// 1. 先序 可以确定根结点
// 2. 中序 根据先序根节点可以找到左右子树
// 3. 根据中序 找到的左右子树对 先序进行分割, 得到左右子树的 根节点, 重复 2, 3步
// 4. 先序分割到最后一个即为叶子结点
ptr buildtree(int a[], int b[], int i, int j, int s, int t)
{
// 遍历到叶子结点, 返回
if (i > j)return NULL;
//创建相对根结点
ptr newroot = new Bnode;
newroot->data = a[i];
// 先找到根结点下标 在先序
int k = s; //保存当前中序首下标,然后++找到根节点
while (k < t && a[i] != b[k]) k++;
// 找到根下标然后递归,直到遍历完, 即为叶子节点,无左右子树
// 确定左子树,在先序, 中序 数组的下标范围, 然后进行构建
/*
左子树在先序数组a的范围
// 确定了 i + 1 为左子树起始下标, 然后在中序计算左子树个数为 k - s, 然后加i, 即得到范围
// i + 1 -> i + k - s 为左子树在 先序数组的 下标范围
左子树在中序数组b的范围
// 根节点下标右边全部
// s -> k - 1
*/
newroot->Lchild = buildtree(a, b, i + 1, i + k - s, s, k - 1);
// 确定右子树,在先序, 中序 数组的下标范围, 然后进行构建
/*
右子树在先序数组a的范围
// i + k - s + 1 -> j
右子树在中序数组b的范围
// 根节点下标右边全部
// k + 1 -> t
*/
newroot->Rchild = buildtree(a, b, i + k - s + 1, j, k + 1, t);
return newroot;
}
void main()
{
int preOrder[5] = {
1, 2, 4, 5, 3 };
int inOrder[5] = {
4, 2 ,5, 1, 3 };
ptr tree = buildtree(preOrder, inOrder, 0, 4, 0, 4);
getchar();
}