C++已知先序遍历序列中序遍历序列建立二叉树;已知后序遍历序列中序遍历序列建立二叉树

如题,已知先序中序/后序中序建立一棵二叉树。

        我们手工建树的时候,比如一个例子:先序序列:ADECFG,中序序列:DBEAFCG。首先我们都会从先序序列中找到第一个元素A,该元素也就是这个树的根。然后再在中序序列中找到一样的元素A,,这样会将中序序列分成两个子序列(DBE) (FCG),分别是左子树与右子树。然后将子序列再看成一棵树。显然这是一个递归的过程。所以只需要把首层的搞清楚。

  • 算法思想:两个数组a[], b[], 分别是树的先序序列和中序序列。p1,q1代表a[]的首尾;p2,q2代表b[的首尾。首先先取a[p1]的值(也就是例子中的A),其次在b[]中找到该值,并返回下标。定义llen(左子树长度),rlen(右子树长度)。求出分得的子序列长度执行递归即可。//函数参数列表 CreateLBTree1(LBTree*& lbt, char a[], char b[], int p1, int q1, int p2, int q2)
  • 算法C++描述
    //先序中序确定树
    void CreateLBTree1(LBTree*& lbt, char a[], char b[], int p1, int q1, int p2, int q2)
    {
    	int llen, rlen;
    	lbt = (LBTree*)malloc(sizeof(LBTree));
    	lbt->data = a[p1];
    	int i;
    	for (i = p2; b[i] != lbt->data; ++i);
    	llen = i - p2;
    	rlen = q2 - i;
    	if (llen)
    		CreateLBTree1(lbt->lchild, a, b, p1 + 1, p1 + llen, p2, p2 + llen - 1);
    	else
    		lbt->lchild = NULL;
    	if (rlen)
    		CreateLBTree1(lbt->rchild, a, b, q1 - rlen + 1, q1, q2 - rlen + 1, q2);
    	else
    		lbt->rchild = NULL;
    }

     

  • 后序中序建树的过程与之相似这里只提供代码:

    //后序中序确定树
    void CreateLBTree2(LBTree*& lbt, char a[], char b[], int p1, int q1, int p2, int q2)
    {
    	int llen, rlen;
    	lbt = (LBTree*)malloc(sizeof(LBTree));
    	lbt->data = a[q1];
    	int i;
    	for (i = p2; b[i] != lbt->data; ++i);
    	llen = i - p2;
    	rlen = q2 - i;
    	if (llen)
    		CreateLBTree2(lbt->lchild, a, b, p1, p1 + llen - 1, p2, p2 + llen - 1);
    	else
    		lbt->lchild = NULL;
    	if (rlen)
    		CreateLBTree2(lbt->rchild, a, b, q1 - rlen, q1 - 1, q2 - rlen + 1, q2);
    	else
    		lbt->rchild = NULL;
    }

    该算法的关键就是在调用递归函数时的参数的赋值。也就是子序列首尾的值。

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 已知先序遍历序列中序遍历序列,可以建立一棵二叉树。具体建立方法如下: 1. 先序遍历序列的第一个元素为根节点,将其在中序遍历序列中找到,可以将中序遍历序列分成左子树和右子树两部分。 2. 根据左子树和右子树的元素个数,可以将先序遍历序列分成左子树和右子树两部分。 3. 对左子树和右子树分别递归建立二叉树。 4. 将左子树和右子树作为根节点的左右子树,连接到根节点上。 5. 递归结束后,得到完整的二叉树。 需要注意的是,如果先序遍历序列中序遍历序列中有重复元素,需要根据先序遍历序列的顺序来确定左右子树的位置。 ### 回答2: 在已知一个二叉树先序遍历序列中序遍历序列的情况下,我们可以通过这两个序列来重建这个二叉树。 首先,我们需要知道先序遍历中序遍历的定义和特点: - 先序遍历:先遍历当前节点,再遍历左子树,最后遍历右子树; - 中序遍历:先遍历左子树,再遍历当前节点,最后遍历右子树。 根据先序遍历的特点,我们可以知道先序遍历的第一个元素必然是根节点,而根据中序遍历的特点,我们可以知道根节点在中序遍历中所处的位置是左子树的所有节点后面。因此,我们可以用先序遍历的第一个元素找到根节点,并在中序遍历中将左子树的所有节点和右子树的所有节点划分出来。 接下来,我们通过递归处理左子树和右子树,可以将整个二叉树重建出来。重建二叉树的方法是: 1. 针对先序遍历中序遍历的左子序列,建立其对应的左子树; 2. 针对先序遍历中序遍历的右子序列,建立其对应的右子树。 因此,我们可以写出递归构建二叉树的伪代码: ``` buildTree(preorder, inorder): if preorder is empty: return null root = TreeNode(preorder[0]) idx = inorder.index(preorder[0]) left_preorder = preorder[1:idx+1] left_inorder = inorder[:idx] right_preorder = preorder[idx+1:] right_inorder = inorder[idx+1:] root.left = buildTree(left_preorder, left_inorder) root.right = buildTree(right_preorder, right_inorder) return root ``` 时间复杂度为 $O(n^2)$,主要是每次都要在中序遍历中查找根节点的位置。优化时间复杂度的方法是,可以使用一个哈希表来记录中序遍历中每个节点的位置,可以将查找根节点的位置的时间复杂度降为 $O(1)$。因此,时间复杂度为 $O(n)$,空间复杂度为 $O(n)$。 ### 回答3: 二叉树是一种常见的数据结构,它由一些节点和连接这些节点的边组成。其中,每个节点至多有两个子节点。如果一个节点没有子节点,则称其为叶节点。底部的节点是深度为1的节点,除非它是根节点,否则它的深度为它父节点的深度加1。在二叉树中,有两种遍历方式,分别是深度优先遍历和广度优先遍历。 对于已知先序遍历序列中序遍历序列建立二叉树,首先需要明确什么是先序遍历中序遍历先序遍历是指先遍历根节点,然后遍历左子树和右子树;中序遍历是指先遍历左子树,然后遍历根节点,最后遍历右子树。因此,通过先序遍历中序遍历,我们可以唯一地确定一个二叉树。 具体建立二叉树的步骤如下: 1. 首先,根据先序遍历序列,确定根节点。 2. 然后,在中序遍历序列中查找根节点的位置,根节点左侧的序列为左子树的中序遍历序列,右侧的序列为右子树的中序遍历序列。 3. 根据左子树的中序遍历序列和右子树的中序遍历序列,可以得到左子树的先序遍历序列和右子树的先序遍历序列。左子树的先序遍历序列的第一个节点为其根节点,右子树的先序遍历序列的第一个节点为其根节点。 4. 重复以上步骤,递归建立左右子树。 需要注意的是,如果先序遍历序列中序遍历序列中含有重复节点,必须先建立左子树,再建立右子树。 总之,通过已知先序遍历序列中序遍历序列建立二叉树需要根据根节点的位置将序列分成左右子树的中序遍历序列,并通过递归的方式逐步建立左右子树。这一过程需要仔细地分析,同时注意处理好重复节点的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值