1. 程式人生 > >面試基礎知識整理 —— 二叉搜尋樹

面試基礎知識整理 —— 二叉搜尋樹

1. 定義

二叉查詢樹(英語:Binary Search Tree),也稱二叉搜尋樹、有序二叉樹(英語:ordered binary tree),排序二叉樹(英語:sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:

  • 若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
  • 若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
  • 任意節點的左、右子樹也分別為二叉查詢樹;
  • 沒有鍵值相等的節點。

摘自維基百科 二叉搜尋樹

2. 實現

二叉搜尋樹節點

package tree;

/**
 * Created by song on 4/8/17.
 *
 * 二叉搜尋樹節點
 */
public class BinaryNode<T extends Comparable> { private T value; private BinaryNode<T> left; private BinaryNode<T> right; public BinaryNode() { /*do nothing*/ } public BinaryNode(T value) { this(value, null, null); } public BinaryNode
(T value, BinaryNode<T> left, BinaryNode<T> right) { this.value = value; this.left = left; this.right = right; } public T getValue() { return value; } public void setValue(T value) { this.value = value; } public BinaryNode<T> getLeft
() { return left; } public void setLeft(BinaryNode<T> left) { this.left = left; } public BinaryNode<T> getRight() { return right; } public void setRight(BinaryNode<T> right) { this.right = right; } }

二叉搜尋樹

package tree;

/**
 * Created by song on 4/8/17.
 * <p>
 * 二叉搜尋樹
 */
public class BinarySearchTree<T extends Comparable> {

    private BinaryNode<T> root;

    public BinarySearchTree() {
        this(null);
    }

    public BinarySearchTree(BinaryNode<T> root) {
        this.root = root;
    }

    public boolean isEmpty() {
        return this.root == null;
    }

    public void clean() {
        this.root = null;
    }

    public T find(T t) {
        return valueAt(find(t, root));
    }

    public T findMin() {
        return valueAt(findMin(root));
    }

    public T findMax() {
        return valueAt(findMax(root));
    }

    public void insert(T t) {
        root = insert(t, root);
    }

    public void remove(T t) {
        root = remove(t, root);
    }

    public void printTree() {

    }

    private T valueAt(BinaryNode<T> node) {
        return node == null ? null : node.getValue();
    }

    @SuppressWarnings("unchecked")
    private BinaryNode<T> find(T x, BinaryNode<T> node) {
        if (node == null) {
            return null;
        }

        if (x.compareTo(node.getValue()) < 0) {
            return find(x, node.getLeft());
        } else if (x.compareTo(node.getValue()) > 0) {
            return find(x, node.getRight());
        } else {
            return node;
        }
    }

    private BinaryNode<T> findMin(BinaryNode<T> node) {
        if (node == null) {
            return null;
        }

        if (node.getLeft() == null) {
            return node;
        }

        return findMin(node.getLeft());
    }

    private BinaryNode<T> findMax(BinaryNode<T> node) {
        if (node == null) {
            return null;
        }

        if (node.getRight() == null) {
            return node;
        }

        return findMax(node.getRight());
    }

    @SuppressWarnings("unchecked")
    private BinaryNode<T> insert(T t, BinaryNode<T> node) {
        if (node == null) {
            node = new BinaryNode<>(t, null, null);
        }

        if (t.compareTo(node.getValue()) < 0) {
            node = insert(t, node.getLeft());
        } else if (t.compareTo(node.getValue()) > 0) {
            node = insert(t, node.getRight());
        } else {
            throw new RuntimeException("duplicate node");
        }

        return node;
    }

    @SuppressWarnings("unchecked")
    private BinaryNode<T> remove(T t, BinaryNode<T> node) {
        if (node == null) {
            return null;
        }

        if (t.compareTo(node.getValue()) < 0) {
            node.setLeft(remove(t, node.getLeft()));
        } else if (t.compareTo(node.getValue()) > 0) {
            node.setRight(remove(t, node.getRight()));
        } else if (node.getLeft() != null && node.getRight() != null) {
            node.setValue(findMin(node.getRight()).getValue());
            node.setRight(remove(node.getValue(), node.getRight()));
        } else {
            node = (node.getLeft() != null) ? node.getLeft() : node.getRight();
        }

        return node;
    }
}