假设已经有了前序遍历和中序遍历的结果,通过一个算法重建这棵树

分析与解法

前序: a b c d e f

后序: d b a e c f

“a”是前序遍历节点的第一个元素,它把中序遍历的结果分为“db”和“ecf”两个部分,这两部分也是“a”的左右子树的遍历结果。

如果能够找到前序遍历中对应的左子树和右子树,就可以把“a”作为当前的根节点,然后依次递归下去,这样就能够依次恢复左子树和右子树的遍历结果。


using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            TreeNode node1 = new TreeNode();
            node1.Data = 1;

            TreeNode node2 = new TreeNode();
            node2.Data = 2;

            TreeNode node3 = new TreeNode();
            node3.Data = 3;

            TreeNode node4 = new TreeNode();
            node4.Data = 4;

            TreeNode node5 = new TreeNode();
            node5.Data = 5;

            TreeNode node6 = new TreeNode();
            node6.Data = 6;

            TreeNode node7 = new TreeNode();
            node7.Data = 7;

            TreeNode node8 = new TreeNode();
            node8.Data = 8;

            TreeNode node9 = new TreeNode();
            node9.Data = 9;

            TreeNode[] nodes1 ={ node1, node2, node4, node7, node3, node5, node8, node6, node9 };
            TreeNode[] nodes2 ={ node7, node4, node2, node1, node8, node5, node3, node6, node9 };

            TreeNode root = ReBuild.ReBuildTree(nodes1, nodes2, 0, 0, nodes1.Length);

            Tree tree2 = new Tree();
            tree2.Root = root;

            Tree.Print2(tree2);

            Console.ReadKey();
        }
    }

    class Tree
    {
        public TreeNode Root;

        /// 
        /// 广度优先遍历二叉树
        /// 
        public static void Print2(Tree tree)
        {
            if (tree.Root == null)
            {
                return;
            }
            else
            {
                Queue> queue = new Queue>();
                queue.Enqueue(tree.Root);

                while (queue.Count != 0)
                {
                    int currentLevelCount = queue.Count;

                    for (int i = 0; i < currentLevelCount; i++)
                    {
                        TreeNode node = queue.Dequeue();

                        if (node.Data != null)
                        {
                            Console.Write(node.Data);
                        }

                        if (node.LeftSon != null)
                        {
                            queue.Enqueue(node.LeftSon);
                        }

                        if (node.RightSon != null)
                        {
                            queue.Enqueue(node.RightSon);
                        }
                    }

                    Console.WriteLine();
                }
            }
        }
    }

    class TreeNode
    {
        public T Data;

        public TreeNode LeftSon;
        public TreeNode RightSon;
    }

    class ReBuild
    {
        public static TreeNode ReBuildTree(TreeNode[] preOrder, TreeNode[] inOrder, int preIndex, int inIndex, int length)
        {
            if (preOrder == null || length == 0)
            {
                return null;
            }
            else if (preOrder.Length != inOrder.Length)
            {
                return null;
            }
            else if (length == 1)
            {
                return preOrder[preIndex];
            }

            for (int i = inIndex; i < inIndex + length; i++)
            {
                if (preOrder[preIndex] == inOrder[i])
                {
                    preOrder[preIndex].LeftSon = ReBuildTree(preOrder, inOrder, preIndex + 1, inIndex, i - inIndex);
                    preOrder[preIndex].RightSon = ReBuildTree(preOrder, inOrder, preIndex + i - inIndex + 1, i + 1, length - i + inIndex - 1);
                }
            }

            return preOrder[preIndex];
        }
    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值