Illustrates a binary tree paper face questions

First, the binary tree &

Tree is composed of nodes and edges, the set of storage elements. The concept of the root node points, parent and child nodes.

FIG: Tree depth = 4; 5 is the root node; 8 Relationship 3 is the same parent-child relationship.

16535373-1a8e4470c9e3c286.png

Binary binary tree, then add the "binary" (binary), it means for distinguishing in the tree. Each sub-node has at most two (child), left child & right child. In many cases the use of a binary tree, such as a binary tree is an arithmetic expression.

FIG: left node is 1/8; 2/3 is the right node;

16535373-76318b6ec690d275.png

Second, the binary search tree BST

As the name suggests, the binary tree added a limit a search. Its requirements: Each node is greater than its left sub-tree element, which is smaller than the right subtree elements.

FIG: Each node in any node is greater than its left subtree, and nodes than any of its right subtree small

16535373-5ae91c052df75d96.png

Java codes are as follows:

public class BinarySearchTree {
    /**
     * 根节点
     */
    public static TreeNode root;

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

    /**
     * 查找
     *      树深(N) O(lgN)
     *      1\. 从root节点开始
     *      2\. 比当前节点值小,则找其左节点
     *      3\. 比当前节点值大,则找其右节点
     *      4\. 与当前节点值相等,查找到返回TRUE
     *      5\. 查找完毕未找到,
     * @param key
     * @return
     */
    public TreeNode search (int key) {
        TreeNode current = root;
        while (current != null
                && key != current.value) {
            if (key < current.value )
                current = current.left;
            else
                current = current.right;
        }
        return current;
    }

    /**
     * 插入
     *      1\. 从root节点开始
     *      2\. 如果root为空,root为插入值
     *      循环:
     *      3\. 如果当前节点值大于插入值,找左节点
     *      4\. 如果当前节点值小于插入值,找右节点
     * @param key
     * @return
     */
    public TreeNode insert (int key) {
        // 新增节点
        TreeNode newNode = new TreeNode(key);
        // 当前节点
        TreeNode current = root;
        // 上个节点
        TreeNode parent  = null;
        // 如果根节点为空
        if (current == null) {
            root = newNode;
            return newNode;
        }
        while (true) {
            parent = current;
            if (key < current.value) {
                current = current.left;
                if (current == null) {
                    parent.left = newNode;
                    return newNode;
                }
            } else {
                current = current.right;
                if (current == null) {
                    parent.right = newNode;
                    return newNode;
                }
            }
        }
    }

    /**
     * 删除节点
     *      1.找到删除节点
     *      2.如果删除节点左节点为空 , 右节点也为空;
     *      3.如果删除节点只有一个子节点 右节点 或者 左节点
     *      4.如果删除节点左右子节点都不为空
     * @param key
     * @return
     */
    public TreeNode delete (int key) {
        TreeNode parent  = root;
        TreeNode current = root;
        boolean isLeftChild = false;
        // 找到删除节点 及 是否在左子树
        while (current.value != key) {
            parent = current;
            if (current.value > key) {
                isLeftChild = true;
                current = current.left;
            } else {
                isLeftChild = false;
                current = current.right;
            }

            if (current == null) {
                return current;
            }
        }

        // 如果删除节点左节点为空 , 右节点也为空
        if (current.left == null && current.right == null) {
            if (current == root) {
                root = null;
            }
            // 在左子树
            if (isLeftChild == true) {
                parent.left = null;
            } else {
                parent.right = null;
            }
        }
        // 如果删除节点只有一个子节点 右节点 或者 左节点
        else if (current.right == null) {
            if (current == root) {
                root = current.left;
            } else if (isLeftChild) {
                parent.left = current.left;
            } else {
                parent.right = current.left;
            }

        }
        else if (current.left == null) {
            if (current == root) {
                root = current.right;
            } else if (isLeftChild) {
                parent.left = current.right;
            } else {
                parent.right = current.right;
            }
        }
        // 如果删除节点左右子节点都不为空
        else if (current.left != null && current.right != null) {
            // 找到删除节点的后继者
            TreeNode successor = getDeleteSuccessor(current);
            if (current == root) {
                root = successor;
            } else if (isLeftChild) {
                parent.left = successor;
            } else {
                parent.right = successor;
            }
            successor.left = current.left;
        }
        return current;
    }

    /**
     * 获取删除节点的后继者
     *      删除节点的后继者是在其右节点树种最小的节点
     * @param deleteNode
     * @return
     */
    public TreeNode getDeleteSuccessor(TreeNode deleteNode) {
        // 后继者
        TreeNode successor = null;
        TreeNode successorParent = null;
        TreeNode current = deleteNode.right;

        while (current != null) {
            successorParent = successor;
            successor = current;
            current = current.left;
        }

        // 检查后继者(不可能有左节点树)是否有右节点树
        // 如果它有右节点树,则替换后继者位置,加到后继者父亲节点的左节点.
        if (successor != deleteNode.right) {
            successorParent.left = successor.right;
            successor.right = deleteNode.right;
        }

        return successor;
    }

    public void toString(TreeNode root) {
        if (root != null) {
            toString(root.left);
            System.out.print("value = " + root.value + " -> ");
            toString(root.right);
        }
    }
}

/**
 * 节点
 */
class TreeNode {

    /**
     * 节点值
     */
    int value;

    /**
     * 左节点
     */
    TreeNode left;

    /**
     * 右节点
     */
    TreeNode right;

    public TreeNode(int value) {
        this.value = value;
        left  = null;
        right = null;
    }
}

Interview a point: to understand the data structure TreeNode

Node data structure, i.e., a left node and a right node of the node points and the value of the node itself. Figure

1483536-4ab125a143be8af2.png

Interview Point two: how to determine the maximum depth of a binary tree or minimum depth

The answer: a simple recursive implementation can, as follows:

int maxDeath(TreeNode node){
    if(node==null){
        return 0;
    }
    int left = maxDeath(node.left);
    int right = maxDeath(node.right);
    return Math.max(left,right) + 1;
}

    int getMinDepth(TreeNode root){
        if(root == null){
            return 0;
        }
        return getMin(root);
    }
    int getMin(TreeNode root){
        if(root == null){
            return Integer.MAX_VALUE;
        }
        if(root.left == null&&root.right == null){
            return 1;
        }
        return Math.min(getMin(root.left),getMin(root.right)) + 1;
    }

Interview Point three: how to determine whether a binary tree is a balanced binary tree

The answer: a simple recursive implementation can, as follows:

    boolean isBalanced(TreeNode node){
        return maxDeath2(node)!=-1;
    }
    int maxDeath2(TreeNode node){
        if(node == null){
            return 0;
        }
        int left = maxDeath2(node.left);
        int right = maxDeath2(node.right);
        if(left==-1||right==-1||Math.abs(left-right)>1){
            return -1;
        }
        return Math.max(left, right) + 1;
    }

Point binary tree is in front of the interview, the interview later point is binary tree search. Soso run the binary codes:

public class BinarySearchTreeTest {

    public static void main(String[] args) {
        BinarySearchTree b = new BinarySearchTree();
        b.insert(3);b.insert(8);b.insert(1);b.insert(4);b.insert(6);
        b.insert(2);b.insert(10);b.insert(9);b.insert(20);b.insert(25);

        // 打印二叉树
        b.toString(b.root);
        System.out.println();

        // 是否存在节点值10
        TreeNode node01 = b.search(10);
        System.out.println("是否存在节点值为10 => " + node01.value);
        // 是否存在节点值11
        TreeNode node02 = b.search(11);
        System.out.println("是否存在节点值为11 => " + node02);

        // 删除节点8
        TreeNode node03 = b.delete(8);
        System.out.println("删除节点8 => " + node03.value);
        b.toString(b.root);

    }
}

The results are as follows:

value = 1 -> value = 2 -> value = 3 -> value = 4 -> value = 6 -> value = 8 -> value = 9 -> value = 10 -> value = 20 -> value = 25 -> 
是否存在节点值为10 => 10
是否存在节点值为11 => null
删除节点8 => 8
value = 1 -> value = 2 -> value = 3 -> value = 4 -> value = 6 -> value = 9 -> value = 10 -> value = 20 -> value = 25 ->

Interview Point four: how to insert binary tree search

Insert, and delete the same will lead to dynamic changes binary search tree. Opposite the insertion puncturing processing logic relatively simple. FIG logic insertion:

16535373-467abb3cbe58a2c4.png
  1. Starting from the root node
  2. If the root is empty, is inserted into the root value
  3. cycle:
  4. If the value is greater than the current node is inserted value, looking left node
  5. If the value is less than the current node value is inserted, to find the right node

Interview 2.5: how to find the binary tree search

Its algorithm complexity: O (lgN), tree depth (N). Figure lookup logic:

16535373-7d48ffe945fd48f2.png
  1. Starting from the root node
  2. Smaller than the current value of the node, then find that the left node
  3. Than the current value of a large node, then find its right node
  4. Equal to the value of the current node, find returns TRUE
  5. Find complete Not Found

Interview 2.5: How to delete binary tree search

More complicated. First, find the deleted node, which is looking for ways: Delete the successor node is the smallest of its right node in the node tree. FIG delete the corresponding logic:

16535373-1118151ce3c4fbbf.png

The results are:

1483536-1c98a826aba1a86b.png
  1. Delete nodes found
  2. If you delete a node in the left node is empty, right node is also null
  3. If you delete a node only one child left or right node node
  4. If you delete the left and right child nodes are not empty

III Summary

Yuan efficient code as a program of interviews and occasionally eat flavor "old altar pickled beef noodles," like a bowl, taste an algorithm, such as BST, always kind of indescribable flavor.

Guess you like

Origin blog.csdn.net/weixin_34122810/article/details/90803526