思路:二叉树的先根序列和中根序列,用两个数组preorder和inorder存放,先根序列的第一个元素值preorder[0]应为二叉树的根上的元素值,在另一个数组中查到此值,设为inorder[k]。此时,数组preorder中从preorder[1]到preorder[k]的序列(长度为k)和数组inorder中从inorder[0]到inorder[k-1](长度为k)的序列,恰好分别是根结点左子树的先根序列和中根序列;数组preorder中从preorder[k+1]到preorder[n-1]的序列(长度为n-k-1)和数组inorder中从inorder[k+1]到inorder[n-1](长度为n-k-1)的序列,恰好分别是根结点右子树的先根序列和中根序列。根据上述分析,先创建根结点,在递归调用自己两次来分别创建左右子树。
时间复杂度:最坏的情况是,每个非叶结点只有左子树,这是两个数组之间需要比较n+(n-1)+---+1=O(n2)次。所以,该算法时间代价为O(n2)。
空间复杂度:存放二叉树的空间O(n)和用于递归调用的栈空间(不超过O(n))。
程序代码:
int create_BTree(PBinTree pbtree,DataType * preorder,DataType * InOrder,int n)
{
int i,k;
int tag1,tag2;
if(n == 0)
{
*pbtree = NULL;
return TRUE;
}
for(i = 0;i if(inorder[i] == preorder[0]) break; if(i == n) { *pbtree = NULL; return FALSE; //输入的先根序列或中根序列有误,创建失败 } k = i; *pbtree = (PBinTreeNode)malloc(sizeof(struct BinTreeNode)); (*pbtree)->info = preorder[0]; tag1 = create_BTree(&(*pbtree)->llink,preorder+1,inorder,k); //递归调用本算法创建左子树 tag2 = create_BTree(&(*pbtree)->rlink,preorder+k+1,inorder+k+1,n-k-1); //递归调用本算法创建右子树 if(tag1 == TRUE && tag2 == TRUE) return TRUE; return FALSE; }