El árbol de búsqueda de algoritmo binario 6 implementa eficientemente la tabla de símbolos

Buenas tardes, lectores y amigos, el blog anterior introdujo la tabla de símbolos basada en listas enlazadas desordenadas y matrices ordenadas, y presentó las limitaciones de la dicotomía utilizada en este blog. Un nuevo algoritmo que conserva las ventajas del algoritmo anterior: la tabla de símbolos implementada por el árbol de búsqueda binario

Los ejemplos de código para este blog son de: Algorithm Algorithm Forth Edition
[US] Robert Sedgewick Kevin Wayne por Xie Luyun

package com.cmh.algorithm;

import edu.princeton.cs.algs4.Queue;

/**
 * @author:起舞的日子
 * @date: 2020/4/7 上午12:30
 * 二叉查找树实现符号表
 */
public class BST<Key extends Comparable<Key>, Value> {

    private Node root;//根结点

    private class Node {
        /**
         * 键
         */
        private Key key;
        /**
         * 值
         */
        private Value val;
        /**
         * 左右节点
         */
        private Node left, right;
        /**
         * 以该节点为根的子树中的结点总数
         */
        private int N;

        public Node(Key key, Value val, int N) {
            this.key = key;
            this.val = val;
            this.N = N;
        }
    }

    private int size(Node x) {
        if (x == null) {
            return 0;
        } else {
            return x.N;
        }
    }

    public int size() {
        return size(root);
    }

    public Value get(Key key) {
        return get(root, key);
    }

    private Value get(Node x, Key key) {
        //在以x为根结点的子树中查找并返回key所对应的值,如果找不到返回null
        if (x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            return get(x.left, key);
        } else if (cmp > 0) {
            return get(x.right, key);
        } else {
            return x.val;
        }
    }

    private Node put(Node x, Key key, Value val) {
        //如果key存在于以x为根结点的子树中则更新它的值;否则将以key和val为键值对的新节点插入该子树
        if (x == null) {
            return new Node(key, val, 1);
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            x.left = put(x.left, key, val);
        } else if (cmp > 0) {
            x.right = put(x.right, key, val);
        } else {
            x.val = val;
        }
        x.N = size(x.left) + size(x.right) + 1;
        return x;
    }

    /**
     * max()
     * min()
     * floor()
     * ceiling()
     */
    public Key min() {
        return min(root).key;
    }

    private Node min(Node x) {
        if (x.left == null) {
            return x;
        }
        return min(x.left);
    }

    public Key floor(Key key) {
        Node x = floor(root, key);
        if (x == null) {
            return null;
        }
        return x.key;
    }

    private Node floor(Node x, Key key) {
        if (x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp == 0) {
            return x;
        }
        if (cmp < 0) {
            return floor(x.left, key);
        }
        Node t = floor(x.right, key);
        if (t != null) {
            return t;
        } else {
            return x;
        }
    }

    /**
     * 排名
     */

    public Key select(int k) {
        return select(root, k).key;
    }

    private Node select(Node x, int k) {
        //返回排名为k的节点
        if (x == null) {
            return null;
        }
        int t = size(x.left);
        if (t > k) {
            return select(x.left, k);
        } else if (t < k) {
            return select(x.right, k - t - 1);
        } else {
            return x;
        }
    }

    public int rank(Key key) {
        return rank(key, root);
    }

    private int rank(Key key, Node x) {
        //返回以x为根结点的子树中小于x.key的键的数量
        if (x == null) {
            return 0;
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            return rank(key, x.left);
        } else if (cmp > 0) {
            return 1 + size(x.left) + rank(key, x.right);
        } else {
            return size(x.left);
        }
    }

    /**
     * 删除
     */

    public void deleteMin() {
        root = deleteMin(root);
    }

    private Node deleteMin(Node x) {
        if (x.left == null) {
            return x.right;
        }
        x.left = deleteMin(x.left);
        x.N = size(x.left) + size(x.right) + 1;
        return x;
    }

    public void delete(Key key) {
        root = delete(root, key);
    }

    /**
     * 即时删除
     */
    private Node delete(Node x, Key key) {
        if (x == null) {
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp < 0) {
            x.left = delete(x.left, key);
        } else if (cmp > 0) {
            x.right = delete(x.right, key);
        } else {
            if (x.right == null) {
                return x.left;
            }
            if (x.left == null) {
                return x.right;
            }
            Node t = x;
            x = min(t.right);
            x.right = deleteMin(t.right);
            x.left = t.left;
        }
        x.N = size(x.left) + size(x.right) + 1;
        return x;
    }

    /**
     * 二叉查找树的范围查找操作
     * 中序遍历
     */

    private void keys(Node x, Queue<Key> queue, Key lo, Key hi) {
        if (x == null) {
            return;
        }
        int cmplo = lo.compareTo(x.key);
        int cmphi = hi.compareTo(x.key);
        if (cmplo < 0) {
            keys(x.left, queue, lo, hi);
        }
        if (cmplo <= 0 && cmphi >= 0) {
            queue.enqueue(x.key);
        }
        if (cmphi > 0) {
            keys(x.right, queue, lo, hi);
        }
    }

   
}


Resumen:

/ **
* 1. No es fácil de entender
* 2. Si el usuario inserta todas las claves en la tabla de símbolos en orden o en orden inverso, puede ocurrir el peor de los casos: puede haber N nodos en la ruta de búsqueda.
* Entonces, hay mejores algoritmos y estructuras de datos, solo guárdelo para el próximo estudio
* /

Publicado 181 artículos originales · elogiado 66 · 200,000 visitas

Supongo que te gusta

Origin blog.csdn.net/meiceatcsdn/article/details/105355932
Recomendado
Clasificación