二叉树遍历操作

时间:2021-07-13 17:27:09

二叉树的简单实现,包含元素插入,主要是前序,中序,后序,层序遍历。最后根据二叉树的前序和中序遍历的数组,先还原二叉树,然后输出其后序遍历的数组

二叉树遍历操作二叉树遍历操作
// 二叉树
import java.util.LinkedList;
import java.util.Queue;

public class BinaryTree {

    private Node root;

    public BinaryTree() {
        this.root = null;
    }

    /**
     * 插入数据到二叉树
     * 
     * @param data
     */
    public void insert(int data) {
        Node newNode = new Node(data);

        if (root == null)
            root = newNode;
        else {
            Node cur = root;
            Node parent;
            // 找插入的位置
            while (true) {
                parent = cur;
                if (data < cur.data) {
                    cur = cur.left;
                    if (cur == null) {
                        parent.left = newNode;
                        return;
                    }
                } else {
                    cur = cur.right;
                    if (cur == null) {
                        parent.right = newNode;
                        return;
                    }
                }
            }
        }
    }

    public void buildTree(int arr[]) {

        for (int i = 0; i < arr.length; i++)
            this.insert(arr[i]);
    }

    /**
     * 前序遍历二叉树
     */
    public void preOrder() {
        this.preOrder(this.root);
    }

    private void preOrder(Node localRoot) {

        if (localRoot != null) {
            System.out.print(localRoot.data + " ");
            this.preOrder(localRoot.left);
            this.preOrder(localRoot.right);
        }
    }

    /**
     * 中序遍历二叉树
     */
    public void inOrder() {
        this.inOrder(this.root);
    }

    private void inOrder(Node localRoot) {

        if (localRoot != null) {
            this.inOrder(localRoot.left);
            System.out.print(localRoot.data + " ");
            this.inOrder(localRoot.right);
        }
    }

    /**
     * 后序遍历二叉树
     */
    public void postOrder() {
        this.postOrder(this.root);
    }

    private void postOrder(Node localRoot) {

        if (localRoot != null) {
            this.postOrder(localRoot.left);
            this.postOrder(localRoot.right);
            System.out.print(localRoot.data + " ");
        }

    }

    /**
     * 层序遍历二叉树
     */
    public void layerOrder() {

        if (this.root == null)
            return;

        Queue<Node> q = new LinkedList<>();
        q.add(root);

        while (!q.isEmpty()) {
            Node node = q.poll();
            System.out.print(node.data);
            System.out.print(" ");
            if (node.left != null)
                q.add(node.left);
            if (node.right != null)
                q.add(node.right);
        }
    }

    class Node {
        int data;
        Node left;
        Node right;

        public Node(int data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }

    /**
     * 根据前序遍历和中序遍历构建二叉树
     * 
     * @param preOrder
     * @param inOrder
     */
    public void initTree(int[] preOrder, int[] inOrder) {

        this.root = this.initTree(preOrder, 0, preOrder.length - 1, inOrder, 0, inOrder.length - 1);
    }

    private Node initTree(int[] preOrder, int preStart, int preEnd, int[] inOrder, int inStart, int inEnd) {

        if (preStart > preEnd || inStart > inEnd)
            return null;
        // 前序遍历的第一个元素是二叉树的根节点
        int rootData = preOrder[preStart];

        Node head = new Node(rootData);

        // 在中序遍历找到根节点的位置
        int rootIndexInOrder = findIndexInArray(inOrder, rootData, inStart, inEnd);
        // 在中序遍历中左子树的偏移量 [inStrat,offSet]闭区间
        int offSet = rootIndexInOrder - inStart - 1;

        // 构建左子树
        Node left = initTree(preOrder, preStart + 1, preStart + offSet + 1, inOrder, inStart, inStart + offSet);

        // 构建右子树
        Node right = initTree(preOrder, preStart + offSet + 2, preEnd, inOrder, rootIndexInOrder + 1, inEnd);

        head.left = left;
        head.right = right;
        return head;

    }

    /**
     * // 在中序遍历找到根节点的位置
     * 
     * @param inOrder  中序遍历数组
     * @param rootData 根节点的数据
     * @param inStart  开始查找的位置
     * @param inEnd    结束查找的位置
     * @return
     */
    private int findIndexInArray(int[] inOrder, int rootData, int inStart, int inEnd) {
        if (inStart > inEnd)
            return -1;
        for (int i = inStart; i <= inEnd; i++) {
            if (inOrder[i] == rootData)
                return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        int pre[] = { 1, 2, 4, 8, 9, 5, 10, 3, 6, 7 };
        int in[] = { 8, 4, 9, 2, 10, 5, 1, 6, 3, 7 };

        BinaryTree bin = new BinaryTree();
        bin.initTree(pre, in);

//        System.out.println("前序:");
//        bin.preOrder();
//        System.out.println("\n" + "中序:");
//        bin.inOrder();
        System.out.println("\n" + "后序:");
        bin.postOrder();
//        System.out.println("\n" + "层序序:");
//        bin.layerOrder();
    }

}
View Code