Hierarchical sequence + mid-order sequence to build a binary tree [Java implementation]

Question description

There is a binary tree with n nodes (the node numbers are from 0 to n-1). Knowing its sequence sequence and its mid-sequence sequence, find the pre-sequence sequence.

Enter description

The first line is an integern(1≤n≤50), indicating the number of nodes in the binary tree;

The second linen is an integer, representing the hierarchical sequence of the binary tree;

The third linen is an integer, representing the in-order sequence of the binary tree.

Output description

Outputn integers, representing the preorder sequence of the binary tree, separated by spaces, and no extra spaces are allowed at the end of the line.

Sample

enter

6
0 2 5 1 4 3
1 2 4 0 5 3

output

0 2 1 4 5 3
image-20230301200928546

Idea analysis

  1. The overall idea is similar to building a binary tree with known preorder/postorder+ mid-order sequence. The construction process is divided into three parts: left subtree, root and right subtree. , the difficulty lies inhow to split the sequence of level-order traversal into three parts: left, root and right

  2. First of all, the first element of the level-order traversal must be the root node in the current subtree, thereby completing the goal of splitting the root node.

    Secondly, since we know the root node, we can divide the left and right subtrees through the root node, which means we know the specific elements of the left subtree and the right subtree.

    Therefore, you only need to use the hash tableleftMap<Integer,Boolean> to mark the left subtree part of the hierarchical sequence as true. At this time, the remaining The unmarked part is the right subtree. At this point, we have achieved the goal of dividing the level-order traversal sequence into three parts: left, root, and right.

  3. Then just perform similar processing like building a binary tree in pre-order+ in mid-order. Each time, the first element is taken out from the hierarchical sequence as the root node< a i=2>, get the position of the root node in the inorder sequence, divide the nodes belonging to the left subtree into the queue , and divide the remaining into rootleftTreerightTree

  4. rootThe left subtree of is the result returned by processing the left subtree part of the in-order sequence and the left subtree part of the hierarchical sequence. The same applies to the right subtree.

Code

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;

import javax.swing.text.AbstractDocument.LeafElement;

public class Main {
    
    
	static ArrayList<Integer> res = new ArrayList<Integer>();

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		LinkedList<Integer> layerList = new LinkedList<Integer>();
		int midArr[] = new int[n];
		for (int i = 0; i < n; i++) {
    
    
			// 层序序列
			layerList.addLast(scanner.nextInt());
		}
		for (int i = 0; i < n; i++) {
    
    
			midArr[i] = scanner.nextInt();
		}
		TreeNode root = buildTreeByLayerAndMid(layerList, midArr, 0, n - 1);
		preOrder(root);
		for (int i = 0; i < n; i++) {
    
    
			System.out.print(res.get(i));
			if (i < n - 1) {
    
    
				System.out.print(" ");
			}
		}
	}

	public static TreeNode buildTreeByLayerAndMid(LinkedList<Integer> layerList, int midArr[], int left2, int right2) {
    
    
		if (layerList.isEmpty()) {
    
    
			return null;
		}
		// 当前节点若属于左子树则value为true
		HashMap<Integer, Boolean> leftMap = new HashMap<Integer, Boolean>();
		TreeNode root = new TreeNode(layerList.poll());
		int count = 0;
		for (int i = left2; i <= right2; i++) {
    
    
			// 找到了根节点
			if (midArr[i] == root.val) {
    
    
				break;
			}
			// 当前遍历到的部分属于左子树
			leftMap.put(midArr[i], true);
			count++;
		}
		LinkedList<Integer> leftTree = new LinkedList<Integer>();
		LinkedList<Integer> rightTree = new LinkedList<Integer>();
		for (Integer integer : layerList) {
    
    
			if (leftMap.getOrDefault(integer, false)) {
    
    
				leftTree.addLast(integer);
			} else {
    
    
				rightTree.addLast(integer);
			}
		}
		// left2+count指向根节点,因此-1后是左子树右边界
		root.left = buildTreeByLayerAndMid(leftTree, midArr, left2, left2 + count - 1);
		root.right = buildTreeByLayerAndMid(rightTree, midArr, left2 + count + 1, right2);
		return root;
	}

	public static void preOrder(TreeNode root) {
    
    
		if (root == null) {
    
    
			return;
		}
		res.add(root.val);
		preOrder(root.left);
		preOrder(root.right);

	}

}

class TreeNode {
    
    
	int val;
	TreeNode left;
	TreeNode right;

	public TreeNode(int val) {
    
    
		this.val = val;
	}

	public TreeNode() {
    
    
	}

}

Guess you like

Origin blog.csdn.net/weixin_45488428/article/details/129289522