【二叉树】由前序和中序结果求后序遍历结果 构造二叉树
前序遍历
前序遍历:若二叉树为空,则空操作返回,否则先访问根节点,再遍历左子树再遍历右子树。
中序遍历:若树为空,则空操作传回,否则从根节点开始(注意不是访问)中序遍历根节点的左子树,然后访问根节点,再中序遍历右子树。
后序遍历:若树为空,则空操作传回,否则从左到右先叶子后节点的方式遍历访问左右子树,最后访问根节点。
前序:根-左子树-右子树
中序:左子树-根-右子树
后序:左子树-右子树-根
前序遍历:ABDGHICEJF
中序遍历:GDIHBAEJCF
后旭遍历:GIHDBJEFCA
运用递归容易求解
由前序和中序遍历构建二叉树 求后序遍历结果
先根据前序遍历找到根节点,再在中序遍历结果中找到根节点的位置,根节点前面就是左子树,右边就是右子树。
以上例:由前序遍历得到A为根节点,由中序遍历得到根节点A左子树为GDIHB,右子树为EJCF。再在前序遍历中找到左子树右子树的根节点。
由上述重复性的算法可知要用递归求解。
下面展示一些 内联代码片
。
// 由前序和中序求后序
// An highlighted block
void CreateTree(BiTree*& root, char* pre_str, char* in_str, int length)
{
if (length == NULL || pre_str == NULL || in_str == 0)
{
return;
}
root = (BiTree*)malloc(sizeof(BiTree));
(root)->data = pre_str[0];
(root)->lchild = NULL;
(root)->rchild = NULL;
char* p = strchr(in_str, pre_str[0]);
if (p != NULL)
{
int nLeft = p - in_str;//头指针相减 左子树长度
CreateTree((root)->lchild, pre_str + 1, in_str, nLeft);
CreateTree((root)->rchild, pre_str +nLeft+ 1, in_str + nLeft + 1, length - nLeft-1);
}
}
后序遍历(递归表示)
// An highlighted block
void fun1(BiTree* root)
{
if (root == NULL)
return;
fun1(root->lchild);
fun1(root->rchild);
cout << root->data;
}
后序遍历(非递归)
由后序和中序遍历构建二叉树 求前序遍历结果
下面展示一些 内联代码片
。
// 直接上代码
// An highlighted block
void CreateTree_2(BiTree*& root, char* re_str, char* in_str, int length)
{
if (length == NULL || re_str == NULL || in_str == 0)
{
return;
}
root = (BiTree*)malloc(sizeof(BiTree));
(root)->data = re_str[length-1];
(root)->lchild = NULL;
(root)->rchild = NULL;
char* p = strchr(in_str, re_str[length-1]);
if (p != NULL)
{
int nLeft = p - in_str;//头指针相减 左子树长度
CreateTree_2((root)->lchild, re_str, in_str, nLeft);//左子树
CreateTree_2((root)->rchild, re_str + nLeft , in_str + nLeft + 1, length - nLeft - 1);//右子树
}
}
下面展示一些 内联代码片
。
// 前序遍历(递归)
// An highlighted block
void fun1(BiTree* root)
{
if (root == NULL)
return;
cout << root->data;
fun1(root->lchild);
fun1(root->rchild);
}