说干就干,先上一篇昨天写的文章。
以一道题目来说明如何建立二叉树。
题目:已知先序遍历,中序遍历 建立二叉树,然后求后序遍历。
e.g. 先序:a b d e i j c f g
中序:d b i e j a f c g
后序:d i j e b f g c a //期望结果
解法:先序中的首元素a 必为该二叉树的根结点,在中序序列里a之前的元素一定是a的左子树部分,a之后的元素一定为a的右子树部分。
所以,可以看作,先序: root | 左子树 | 右子树
中序: 左子树 | root | 右子树
由此, 我们可以递归的得到该二叉树。 即,先得到root根结点,然后,对左子树进行同样的操作,然后对右子树进行同样的操作。
所以建立二叉树的过程可看作:
MakeBinaryTree(...)
{
得到root 根结点
MakeBinaryTree( 左子树 );
MakeBinaryTree( 右子树 );
}
代码实现:C++语言: 贴彩色代码可用:http://fayaa.com/code/new/
using namespace std;
typedef struct BinaryTreeNode
{
char data;
BinaryTreeNode * leftChild;
BinaryTreeNode * rightChild;
}Node;
void MakeBinaryTree(Node** root, char* preOrder, char* midOrder, int length)
{
if (length == 0)
{
(*root) = NULL;
return;
}
(*root) = new Node;
(*root)->data = *preOrder;
char * rootplace = strchr(midOrder, (*root)->data);
if (rootplace == NULL)
{
cout <<"input wrong order sample!"<<endl;
}
int leftTreeLength = strlen(midOrder) - strlen(rootplace);
int rightTreeLength = length - leftTreeLength - 1;
MakeBinaryTree(&(*root)->leftChild, preOrder+1, midOrder, leftTreeLength);
MakeBinaryTree(&(*root)->rightChild, preOrder+leftTreeLength+1, rootplace+1, rightTreeLength);
}
void PostTraverse(Node* root)
{
if (root == NULL)
return;
PostTraverse(root->leftChild);
PostTraverse(root->rightChild);
cout << root->data;
}
int main(int argc, const char** argv)
{
char pre[] = "abdeijcfg";
char mid[] = "dbiejafcg";
Node* r;
MakeBinaryTree(&r, pre, mid, strlen(pre));
PostTraverse(r);
return 0;
}
题外话,
1 如果已知中序,后序遍历结果,求先序。由于后序可看作 左子树 | 右子树 | 根,可以考虑从后向前操作,这样可以先确定根。
2 如何删除树呢?
3 如何非递归实现呢?