Árbol de búsqueda binaria (BST) --- implementación java

1. Definición

Un árbol de búsqueda binario (BST) es un árbol binario cuyo valor de cada nodo es mayor que cualquier nodo del elemento secundario izquierdo y menor que cualquier nodo del elemento secundario derecho.

Segundo, la estructura de datos.

public class BinarySearchTree<T extends Comparable<? super T>>  {

    private TreeNode<T> root;

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

class TreeNode<T>{
    T data;
    TreeNode lchild;
    TreeNode rchild;

    public TreeNode(T data) {
        this(data,null,null);
    }

    public TreeNode(T data, TreeNode lchild, TreeNode rchild) {
        this.data = data;
        this.lchild = lchild;
        this.rchild = rchild;
    }


}

Tres, contiene método

Devuelve verdadero si los datos X existen en el árbol; de lo contrario, devuelve falso.
Solo necesitamos comenzar a atravesar desde el nodo raíz, si el nodo actual es menor que X, luego recurrir a la izquierda, de lo contrario recursivo a la derecha hasta que encontremos X o lleguemos al final del árbol.

 public boolean contains(T x){
        return  contains(x,root);
    }
    private boolean contains(T x, TreeNode<T> root) {
        if (root==null){
            return false;
        }
        int result=x.compareTo(root.data);
        if (result<0){
            return contains(x,root.lchild);
        }else if (result>0){
            return contains(x,root.rchild);
        }else {
            return true;
        }

    }

Cuarto, encuentra el mínimo y el máximo

Un árbol de búsqueda binario, el valor mínimo debe encontrarse recursivamente de acuerdo con el subárbol izquierdo hasta la parte inferior del árbol
1. Si el nodo raíz está vacío, devuelve vacío
2. Si el subárbol izquierdo está vacío, devuelve el nodo raíz
3. De lo contrario, desde El niño izquierdo comienza y continúa repitiendo desde 1.

 public TreeNode<T> findMax(TreeNode<T> root){
        if (root==null){
            return null;
        }
        while (root.rchild!=null){
            root=root.rchild;
        }
        return root;
    }

Encontrar el valor máximo es lo contrario, hacer un bucle desde el nodo raíz al subárbol derecho.

public TreeNode<T> findMax(TreeNode<T> root){
        if (root==null){
            return null;
        }
        while (root.rchild!=null){
            root=root.rchild;
        }
        return root;
    }

Cinco, inserta un nodo

También puede usar la forma recursiva de contiene.
Si se encuentra X, el nodo ya existe y no hace nada; de lo contrario, se inserta en el último nodo en la ruta transversal.

public TreeNode<T> insert(T x){
        if (x==null){
            throw new IllegalArgumentException("参数为空");
        }
        return insert(x,root);
    }
    private TreeNode<T> insert(T x,TreeNode<T> t){
    	//当前节点为空,构建一个新的节点插入x
        if (t==null){
            return new TreeNode<>(x);
        }
        int result=x.compareTo(t.data);
        if (result<0){
        	//向左递归
            t.lchild=insert(x,t.lchild);
        }else if (result>0){
     	   //向右递归
            t.rchild=insert(x,t.rchild);
        }
        return t;
    }

Seis, eliminar un nodo

La eliminación del nodo X se puede dividir aproximadamente en tres casos:

  1. Si X es un nodo hoja, elimínelo directamente
  2. Si X tiene un hijo, colóquelo en la posición actual del nodo
  3. Si X tiene dos hijos, encuentre el nodo Y más pequeño del hijo derecho y colóquelo en la posición del nodo X que se va a eliminar, de modo que los hijos izquierdos de X sean aún más pequeños que él. Ahora solo necesita eliminar el Y del hijo derecho Eso es todo
 public void remove(T x){
        if (x==null){
            return;
        }
        remove(x,root);
    }

    /**
     * 删除一个节点
     * 1.如果是叶子节点,则直接删除
     * 2.如果有一个孩子,让当前节点等于那个孩子
     * 3.如果有两个孩子,让当前节点的值等于右孩子中最小的一个节点的值,然后再同样的方法删除右孩子最小值的节点
     * @param x
     * @param root
     * @return
     */
    private TreeNode<T> remove(T x,TreeNode<T>root){
        if (root==null){
            return null;
        }

        int result=x.compareTo(root.data);
        if (result<0){
            root.lchild=remove(x,root.lchild);
        }else if (result>0){
            root.rchild=remove(x,root.rchild);
        }else if (root.lchild!=null&&root.rchild!=null){ //找到待删除节点,且有两个孩子
        	//让当前节点值等于右孩子最小的节点值
            root.data= (T) findMin(root.rchild).data;
            //在右孩子中删除上一步找到的最小的值
            root.rchild=remove(root.data,root.rchild);
        }else {
            root=root.lchild==null?root.rchild:null;
        }
        return root;
    }

Encontrar la altura de un nodo es simple:

 public int height(TreeNode<T> root){
        if (root==null){
            return -1;
        }
        return 1+Math.max(height(root.lchild),height(root.rchild));
    }

Resumen:
el tiempo de ejecución de un árbol de búsqueda binario depende de la forma del árbol, que a su vez depende del orden en que se insertan los datos. Por lo tanto, el mejor caso es un árbol binario completo; pero en el peor de los casos, hay N nodos en la ruta de búsqueda, es decir, los nodos izquierdo y derecho están alineados debajo de una ruta.

El aumento del orden de magnitud en el peor de los casos en el tiempo de ejecución:
búsqueda: N
inserto: N
caso promedio:
hallazgo hit: 1.39lgN
inserto: 1.39lgN
admite operaciones relacionadas ordenadas

Publicado 75 artículos originales · alabanza ganado 13 · vistas 8369

Supongo que te gusta

Origin blog.csdn.net/weixin_43696529/article/details/104697184
Recomendado
Clasificación