1. 程式人生 > 其它 >java實現二叉查詢樹

java實現二叉查詢樹

java實現二叉查詢樹

public class BinarySortTree<K extends Comparable<K>, V> {

    public BinaryNode<K, V> getRoot() {
        return root;
    }

    public void setRoot(BinaryNode<K, V> root) {
        this.root = root;
    }

    private BinaryNode<K, V> root;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    
static class BinaryNode<K, V> { private K key; private V value; private BinaryNode<K, V> left; private BinaryNode<K, V> right; public BinaryNode(K key, V value) { this.key = key; this.value = value; } // @Override
// public String toString() { // return "BinaryNode{" + // "key=" + key + // ", value=" + value + // '}'; // } } /** * 二叉排序樹的搜尋,最小時間複雜度lg2(n) * 1.key小於當前節點則遞歸向左,大於遞歸向右,等於返回value * 2.遞迴到最後也沒有找到則返回null * *
@param key * @return */ public V search(K key) { BinaryNode<K, V> cursor = this.root; if (cursor == null) { return null; } while (cursor != null) { K k = cursor.key; if (key.compareTo(k) < 0) { cursor = cursor.left; } else if (key.compareTo(k) > 0) { cursor = cursor.right; } else { return cursor.value; } } return null; } /** * 插入-非遞迴 * 1.先判斷根節點是否為空,為空則構造根節點 * 2.如果根節點不為空,則判斷待插入資料與根節點大小 * 3.如果value小於根,則向左,否則向右,如果等於,則資料已存在不需要處理 * 4.如果左為空,則用value構造左,右為空則構造右 * * @param value * @return */ public void insert(K key, V value) { if (root == null) { root = new BinaryNode<>(key, value); return; } BinaryNode<K, V> cursor = root; while (true) { K k = cursor.key; if (key.compareTo(k) < 0) { if (cursor.left == null) { cursor.left = new BinaryNode<>(key, value); return; } cursor = cursor.left; } else if (key.compareTo(k) > 0) { if (cursor.right == null) { cursor.right = new BinaryNode<>(key, value); return; } cursor = cursor.right; } else { cursor.value = value; } } } /** * 刪除的情況比較複雜,分為幾種情況: * 1.葉子節點,無左右孩子,直接將cursor的父節點的孩子cursor設為null * 2.有左孩子,沒有右孩子,將左孩子拉到自己的位置 * 3.有右孩子,沒有左孩子,將右孩子拉到自己的位置 * 4.有左右孩子,獲取左孩子的最大節點(肯定是葉子節點),放在自己的位置,然後將原節點刪除 * * @param key */ public void remove(K key) { BinaryNode<K, V> cursor = this.root; if (cursor == null) { return; } BinaryNode<K, V> cursorParent = null; while (cursor != null) { K k = cursor.key; if (key.compareTo(k) < 0) { cursorParent = cursor; cursor = cursor.left; } else if (key.compareTo(k) > 0) { cursorParent = cursor; cursor = cursor.right; } else { doRemove(cursorParent, cursor); return; } } } private void doRemove(BinaryNode<K, V> cursorParent, BinaryNode<K, V> cursor) { if (cursor.left == null && cursor.right == null) { if (cursor == cursorParent.left) { cursorParent.left = null; } else { cursorParent.right = null; } } else if (cursor.right == null) { if (cursor == cursorParent.left) { cursorParent.left = cursor.left; } else { cursorParent.right = cursor.left; } } else if (cursor.left == null) { if (cursor == cursorParent.left) { cursorParent.left = cursor.right; } else { cursorParent.right = cursor.right; } } else { //左右都不為null //選擇左子樹最大節點,放在自己的位置 //左子樹最大節點刪除 BinaryNode<K, V> maxLeft = findMax(cursor.left); remove(maxLeft.key); cursor.setKey(maxLeft.key); cursor.setValue(maxLeft.value); } } public BinaryNode<K, V> findMax(BinaryNode<K, V> root) { if (root == null) { return null; } BinaryNode<K, V> cursor = root; while (true) { if (cursor.right == null) { return cursor; } else { cursor = cursor.right; } } } public BinaryNode<K, V> findMin(BinaryNode<K, V> root) { if (root == null) { return null; } BinaryNode<K, V> cursor = root; while (true) { if (cursor.left == null) { return cursor; } else { cursor = cursor.left; } } } /** * 中根遍歷-遞迴實現 * * @param t */ public void midOrder(BinaryNode<K, V> t) { if (t == null) { return; } midOrder(t.left); System.out.println(t); midOrder(t.right); } public static void main(String[] args) { BinarySortTree<Integer, Integer> tree = new BinarySortTree<>(); tree.insert(3, 3); tree.insert(1, 1); tree.insert(2, 2); tree.insert(4, 4); tree.insert(5, 5); System.out.println(tree.getRoot()); tree.remove(3); System.out.println(tree.getRoot()); tree.remove(4); System.out.println(tree.getRoot()); tree.remove(5); System.out.println(tree.getRoot()); } }