博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重建二叉树
阅读量:5164 次
发布时间:2019-06-13

本文共 2131 字,大约阅读时间需要 7 分钟。

关于二叉树的重建,我总结如下,并以图文的形式展示:

一颗二叉树,已知先序遍历和中序遍历,要求还原出二叉树,问题不难,关键是细节:

思想:

1、先序遍历序列的第一个元素一定定是根节点,可以由此获取二叉树的根节点。

2、在中序遍历序列中查找到根节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列一定在根节点的左子树中,而根节点右边的序列一定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点。

以上过程,递归就显得很重要:

先上一张图:

假设这是需要我们重新构建的二叉树。

此二叉树的前序遍历为:1,2,4,7,3,5,6,8

                   中序遍历为:4,7,2,1,5,3,8,6

再看:

同样的方法在子树中递归重建子树,以下是代码:

//声明重构BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder);//重构BinaryTreeNode* Construct(int* preorder, int* inorder, int length){    if(preorder == NULL || inorder == NULL || length <= 0)        return NULL;	//传给的是前 和 中 序遍历的范围(指针)    return ConstructCore(preorder, preorder + length - 1,        inorder, inorder + length - 1);}BinaryTreeNode* ConstructCore(    int* startPreorder, int* endPreorder,     int* startInorder, int* endInorder){    //前序遍历序列的第一个数字是根结点的值    int rootValue = startPreorder[0];	//重构第一个根节点    BinaryTreeNode* root = new BinaryTreeNode();    root->m_nValue = rootValue;    root->m_pLeft = root->m_pRight = NULL;	//前序的头和尾相等的时候    if(startPreorder == endPreorder)    {		//并且中序头和尾也相等,前序头和中序头相等,只说明只有一个节点		if (startInorder == endInorder && *startPreorder == *startInorder)		{            return root;		}    }    // 在中序遍历中找到根结点的值    int* rootInorder = startInorder;	while (rootInorder <= endInorder && *rootInorder != rootValue)	{        ++ rootInorder;	}	if (rootInorder == endInorder && *rootInorder != rootValue)	{		cout << "非法序列" << endl;		return;	}	//while循环结束,跳过,意思是找到了根节点	//求出左子树的长度leftLength    int leftLength = rootInorder - startInorder;  //虽然是指针相减,但指针内部也是整数    int* leftPreorderEnd = startPreorder + leftLength; //找到前序遍历左子树最后一个节点    if(leftLength > 0)    {        // 构建左子树		//startPreorder + 1 原来前序的头往前走一个        root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd,             startInorder, rootInorder - 1);    }    if(leftLength < endPreorder - startPreorder)    {        // 构建右子树        root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,            rootInorder + 1, endInorder);    }    return root;}
赐教!

转载于:https://www.cnblogs.com/li-ning/p/9490012.html

你可能感兴趣的文章
解除与设置计算机锁定
查看>>
PAT A1110 Complete Binary Tree (25 分)——完全二叉树,字符串转数字
查看>>
OpenCV学习笔记-\doc\tutorials\core\basic_linear_transform
查看>>
安装 gradle
查看>>
只输入数字
查看>>
抽屉问题 吃糖果
查看>>
js常用的数组去重方法
查看>>
Setting up a Reverse Proxy using IIS, URL Rewrite and ARR
查看>>
bzoj 4818: [Sdoi2017]序列计数
查看>>
生成对抗网络(Generative Adversarial Network)阅读笔记
查看>>
GIT原理和常用命令速成
查看>>
Jmeter之集合点与关联
查看>>
springboot整合webservice
查看>>
字符串匹配KMP算法详解
查看>>
单词查找排序输出
查看>>
TCP三次握手和四次挥手及用户访问网页流程
查看>>
echo常用操作
查看>>
算法笔记
查看>>
LeetCode 237. Delete Node in a Linked List 删除链表结点(只给定要删除的结点) C++/Java...
查看>>
LCA倍增模板
查看>>