고전적인 알고리즘 문제 - 기초 - 이진 트리의 재건

문제 설명

설명 제목
입력 결과와 이진 트리 재 구축의 전순 주사에 이진 트리의 전순 주사.
가정 된 결과 전순 주사 순서와 입력 된 숫자에는 반복되지 않습니다
예 :
전순 주사 순서 {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; }
}

문제 해결 아이디어

핸드 감소

이 문제는 프로그래밍 문제이지만,하지만 자주 묻는 등 여행, 방향 채울
나무 알려져을 :

  • 전순 주사 순서 {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- 발견되고 따라서이 하위 트리 4,7 왼쪽 오른쪽 하위 트리, 다음과 같은 구조 비어 있습니다 :

그리고, 전자 (7)의 전순 주사의 루트 노드 일 수있다 4,7, 4 서브 트리 아이의 오른쪽 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