Классическая задача алгоритма - фундамент - Реконструкция бинарного дерева

Описание проблемы

Описание Заголовок
входного результат и предпорядок обход бинарного дерева в обходе двоичного дерева восстанавливания.
Предполагаемые результаты обходе порядка и числа входного нет повторения
Примера:
предпорядок последовательности обхода {1, 2,4,7,3,5,6,8} и {4,7,2,1,5,3,8,6} последовательность предпорядок
способа - прототипа

public TreeNode reConstructBinaryTree(int [] pre,int [] in)
class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode(int x) { val = x; }
}

Проблема решения идеи

сокращение рук

Хотя эта проблема является проблемой программирования, но часто заполняющий путь поездка, такими как задается вопрос:
Known для дерева:

  • Последовательность обходе {1,2,4,7,3,5,6,8}
  • Последовательность обхода Симметричного {4,7,2,1,5,3,8,6}

Ища дерево postorder обхода . Принцип решения этой проблемы есть два, во - первых, корень появляется предзаказ обходе начало , а затем предзаказа в левой и правой элементов суб-дерева появляются в левой и правой частях корня .
Выше проблемы, например, первый порядок обход назад Смотрите, мы знаем , что корень дерева 1, а затем перейти к предзаказу, она находится на левом 1 4,7,2, справа есть 5,3,8,6. Чтобы знать , корень левого поддерева 4,7,2, а правое поддерево 5,3,8,6.

Итак , как проверить форму левого поддерева этого? Так же , как с помощью метода: чтобы подтвердить предыдущую последовательность корневой узел обхода и подтвердить левый и правый суб-дерево в порядке обхода .
4, 7, 2 последовательности, например, предварительный заказ обхода может просматривать 2 сначала появляется, следовательно , 2 корневой узел поддерева , затем в порядке обхода, находятся на левом 2 4,7, 2 , таким образом , левое поддерево 4,7 , правое поддерево пусто, следующая структура:

Затем к югу дерево 4,7, 4, которая может быть корневой узел в обходе бывшей 7 является правая сторона 4 ребенка.

Повторное использование вышеуказанных правил, вы можете восстановить всю структуру дерева, ниже полные динамические презентации:

Восстановили описанным выше способом, чтобы получить первоначальную форму дерева:

ПРИРОДНЫЙ предзаказ знать После {7,4,2,5,8,6,3,1}.

Программирование Восстановление

После изучения восстановления вручную деревьев, мы будем писать код, чтобы добиться восстановления дерева, которое кратко, как считалось ранее:

  • Подтверждено путем обхода корневой преамбулы
  • Пересекая подтвердить левое и правое поддерево по Симметричному
  • Описанный выше процесс рекурсивно, знать для восстановления узлов листа

В конкретной реализации коды, используя рекурсивный алгоритм друг от друга, но и с использованием переменной inRootIndex для различения левого и правого поддерева.

Соответствующий код

package com.shellmad;

public class Solution {

    public static void main(String[] args) {
        int[] pre = {1,2,4,7,3,5,6,8};
        int[] in = {4,7,2,1,5,3,8,6};
        Solution solution = new Solution();
        TreeNode root = solution.reConstructBinaryTree(pre, in);
        System.out.println(root);
    }

    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        // 检查输入
        if (pre == null || in == null || pre.length == 0 || in.length == 0
            || pre.length != in.length) {
            return null;
        }

        // 判断是否是叶子节点
        if (pre.length == 1) {
            return new TreeNode(pre[0]);
        }

        // 在中序遍历中找到根节点的位置
        int rootIndex = -1;
        for (int index = 0; index < in.length; index++) {
            if (pre[0] == in[index]) {
                rootIndex = index;
                break;
            }
        }

        if (rootIndex == -1) {
            return null;
        }

        // 创建根节点
        TreeNode root = new TreeNode(pre[0]);

        // 递归构建左子树
        if (rootIndex != 0) {
            int lSubTreeLegth = rootIndex;
            int[] leftPre = new int[lSubTreeLegth];
            int[] leftIn = new int[lSubTreeLegth];

            for (int index = 0; index < lSubTreeLegth; index++) {
                leftPre[index] = pre[1 + index];
                leftIn[index] = in[index];
            }

            root.left = reConstructBinaryTree(leftPre, leftIn);
        }

        // 递归构建右子树
        if (rootIndex != in.length - 1) {
            int rSubTreeLegth = in.length - 1 - rootIndex;
            int[] rightPre = new int[rSubTreeLegth];
            int[] rightIn = new int[rSubTreeLegth];

            for (int index = 0; index < rSubTreeLegth; index++) {
                rightPre[index] = pre[rootIndex + 1 + index];
                rightIn[index] = in[rootIndex + 1 + index];
            }

            root.right = reConstructBinaryTree(rightPre, rightIn);
        }
        return root;
    }
}




class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

рекомендация

отwww.cnblogs.com/shellmad/p/11706164.html