更多题目:《 剑指offer》 目录索引
问题描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输
入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},则重建二叉树并输出它的头结点。
思路:
前序遍历的第一个节点为二叉树的头节点
根据头节点在中序遍历中找出头节点,并以此为分界点划分左子树和右子树
由于前序遍历都是先遍历子树的头节点,故此在前序中找左子树的头节点,和右子树的头节点
根据头节点在中序遍历中找寻分界点,划分左子树和右子树,依次类推
代码:
typedef struct BTNode
{
int _data;
struct BTNode* _left;
struct BTNode* _right;
}BTNode;
BTNode* BuyBTNode(int x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->_data = x;
node->_left = NULL;
node->_right = NULL;
return node;
}
BTNode* Construct(int* prev, int* inorder, int len)
{
if (prev == NULL || inorder == NULL || len < 0)
return NULL;
return ConstructCore(prev, prev + len - 1, inorder, inorder + len - 1);
}
BTNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder)
{
//前序的第一个值为根节点
BTNode* root = BuyBTNode(*startPreorder);
//在中序中找根,以该值为分界点,左边为左子树,右边为右子树
int value = *startPreorder;
int* inorder = startInorder;
while (inorder <= endInorder)
{
if (value == *inorder)
{
break;
}
inorder++;
}
//保存左子树长度
int leftlen = inorder - startInorder;
//保存右子树根,中序找到根后,左边为左子树,对应前序中除去根节点和左子树,即为右子树的第一个节点
int* righttree = startPreorder + leftlen ;
//创建左子树,左子树的前序为,第二个+节点数(长度),中序为第一个节点---根节点的前一个
if (leftlen > 0)
{
root->_left = ConstructCore(startPreorder + 1, righttree, startInorder, inorder-1);
}
//创建右子树,前序为,根节点+左子树节点(长度)-----最后,中序为根节点的下一个----最后
if (leftlen < endPreorder - startPreorder)
{
root->_right = ConstructCore(righttree + 1, endPreorder, inorder + 1, endInorder);
}
return root;
}
void Test()
{
BTNode* root;
int prevorder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int inoeder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
int len = sizeof(prevorder) / sizeof(prevorder[0]);
root = Construct(prevorder, inoeder, len);
printf("%d\n", root->_data);
}
void Test1()
{
const int length = 5;
int preorder[length] = { 1, 2, 3, 4, 5 };
int inorder[length] = { 5, 4, 3, 2, 1 };
BTNode* root = Construct(preorder, inorder, length);
printf("%d\n", root->_data);
}
void Test2()
{
const int length = 5;
int preorder[length] = { 1, 2, 3, 4, 5 };
int inorder[length] = { 1, 2, 3, 4, 5 };
BTNode* root = Construct(preorder, inorder, length);
printf("%d\n", root->_data);
}
void Test3()
{
const int length = 1;
int preorder[length] = { 1 };
int inorder[length] = { 1 };
BTNode* root = Construct(preorder, inorder, length);
printf("%d\n", root->_data);
}
void Test4()
{
BTNode* root = Construct(NULL, NULL, 0);
}
int main()
{
Test();
Test1();
Test2();
Test3();
Test4();
system("pause");
return 0;
}