Buscar - Búsqueda de tabla de árbol - Árbol de clasificación binaria

Definición de árbol de clasificación binaria

El árbol de clasificación binaria, también conocido como árbol de búsqueda binaria, es un árbol binario especial útil tanto para ordenar como para buscar.
Definición:
Un árbol de clasificación binario es un árbol binario vacío o un árbol binario con las siguientes propiedades:

  • Las claves de todos los nodos del subárbol izquierdo son más pequeñas que las claves del nodo raíz;
  • Las claves de todos los nodos en el subárbol derecho son mayores que las claves del nodo raíz;
  • El subárbol izquierdo y el subárbol derecho son cada uno un árbol binario.
//二叉排序树结点
typedef int KeyType;
typedef struct {
    
    
    KeyType key;
    char info[];
}ElemType;

typedef struct BSTNode{
    
    
    ElemType data;
    struct BSTNode * lchild;
    struct BSTNode * rchild;
}BSTNode,*BSTree;

Insertar descripción de la imagen aquí

Valor del nodo del subárbol izquierdo < valor del nodo raíz < valor del nodo del subárbol derecho "
> \quad\qquad\qquad\qquad \Downarrow">
Realice un recorrido en orden para obtener una secuencia ordenada creciente.

encontrar operación

Debido a que un árbol de clasificación binario puede considerarse como una lista ordenada, la búsqueda en un árbol de clasificación binario es similar a una búsqueda binaria y también es un proceso de reducción gradual del alcance de la búsqueda.

Descripción del algoritmo:

① Si el árbol de clasificación binario está vacío, la búsqueda falla y se devuelve un puntero nulo.
② Si el árbol de clasificación binario no está vacío, compare la clave dada con la clave del nodo raíz;

  • Si son iguales, la búsqueda es exitosa y se devuelve el puntero del nodo raíz;
  • Si es menor que el nodo raíz, busque recursivamente en el subárbol izquierdo.
  • Si es mayor que el nodo raíz, busque recursivamente en el subárbol derecho.
    Descripción del algoritmo:
BSTree SearchBST(BSTree T,KeyType key){
    
    
    if((!T)||key==T->data.key)
        return T;
    else if(key<T->data.key)
        return SearchBST(T->lchild,key);
    else
        return SearchBST(T->rchild,key);
}

operación de inserción

La operación de inserción de un árbol ordenado binario se basa en la búsqueda. Para insertar un nodo * S con un valor clave de clave en un árbol ordenado binario, debe buscar hacia abajo desde el nodo raíz e insertarlo solo cuando haya un nodo con una clave igual a clave en el medio del árbol. El nodo recién insertado debe ser un nodo hoja recién agregado y ser el nodo secundario izquierdo o derecho del último nodo visitado en la ruta de búsqueda cuando la parte de búsqueda es exitosa.

Descripción del algoritmo

① Si el árbol de clasificación binario está vacío, el nodo *S que se va a insertar se inserta en el árbol vacío como nodo raíz.
② Si el árbol de clasificación binario no está vacío, compare la clave proporcionada con la clave del nodo raíz (T->data.key):

  • Si clave<T->data.key, inserte *S en el subárbol izquierdo;
  • Si clave>T->data.key, inserte *S en el subárbol derecho.
int InsertBST(BSTree &T, ElemType e) {
    
    
    if (!T) {
    
    
        T = (BSTree) malloc(sizeof(BSTNode));
        T->data = e;
        T->lchild = T->rchild = NULL;
        return 1;
    } else if (e.key == T->data.key)
        return 0;
    else if (e.key < T->data.key)
        return InsertBST(T->lchild, e);
    else if (e.key > T->data.key)
        return InsertBST(T->rchild, e);
}

Eliminar operación

El nodo eliminado puede ser cualquier nodo en el árbol de clasificación binaria. Una vez eliminado el nodo, los punteros de su nodo principal y sus nodos relacionados deben modificarse de acuerdo con su posición para mantener las características del árbol de clasificación binaria.
Insertar descripción de la imagen aquí

Si el nodo eliminado z es un nodo hoja, se eliminará directamente, lo que no se comportará como un árbol de clasificación binario.
Insertar descripción de la imagen aquí

Si el nodo z tiene solo un subárbol izquierdo, dejemos que el subárbol de z se convierta en el subárbol del nodo padre de z, reemplazando la posición de z.
Insertar descripción de la imagen aquí
Si el nodo z tiene solo el subárbol derecho, dejemos que el subárbol de z se convierta en el subárbol del nodo padre de z, reemplazando la posición de z.
Insertar descripción de la imagen aquí
Si los subárboles izquierdo y derecho del nodo z no están vacíos, reemplace z con el predecesor directo de z y luego elimine el predecesor directo del árbol de clasificación binario, convirtiendo así a la situación ① o ②.
Insertar descripción de la imagen aquí
Si los subárboles izquierdo y derecho del nodo z no están vacíos, reemplace z con el sucesor directo de z y luego elimine este sucesor directo del árbol de clasificación binario, convirtiendo así a la situación ① o ②.

Descripción del algoritmo:

  1. Primero, busque el nodo que desea eliminar con la clave de palabra clave:
    ① Si el nodo eliminado z es un nodo hoja, se eliminará directamente y no tendrá las características de un árbol de clasificación binario.
    ② Si el nodo z tiene solo un subárbol izquierdo o solo un subárbol derecho, dejemos que el subárbol de z se convierta en el subárbol del nodo padre de z, reemplazando la posición de z.
    ③ Si los subárboles izquierdo y derecho del nodo z no están vacíos, reemplace z con el sucesor directo (o predecesor directo) de z, y luego elimine el sucesor directo (o predecesor directo) del árbol de clasificación binaria, convirtiendo así a ① o ② situación.
void DeleteBST(BSTree &T, KeyType key) {
    
    
    BSTNode *z = T; //待删除的结点
    BSTNode *f = NULL; //待删除结点 *z 的双亲结点
    /**----------------------- while循环从根开始查找关键字等于key的结点*z -----------------------*/
    while (z) {
    
    
        if (z->data.key == key)
            break; //找到关键字等于key的结点 *z
        f = z; //*f 为 *p的双亲结点
        if (z->data.key > key)
            z = z->lchild; //在*z 的左子树中继续查找
        else
            z = z->rchild;    //在 *p的右子树中继续查找
    }

    if (!z)return; //找不到待删除的结点;
    /**------------ 考虑3中情况实现p所指子树内部的处理:*p左右子树不为空、无左子树、无右子树 ------------*/
    BSTNode *q = z;
    if (z->lchild && z->rchild) {
    
     //待删除结点*z 左右子树均不为空
        BSTNode *s = z->lchild;
        while (s->rchild) {
    
     //在*p的左子树中继续查找其前驱结点,即最右下结点
            q = s;
            s = s->rchild; //向右到尽头
        }
        z->data = s->data; //s指向待删除结点的前驱
        if (q != z)
            q->rchild = s->lchild; //重接*q的右子树
        else
            q->lchild = s->lchild; //重接*q的左子树
        delete s;
        return;
    } else if (!z->rchild) {
    
    //待删除结点*p无右子树结点,只需重接其左子树
        z = z->lchild;
    } else if (!z->lchild) {
    
    //待删除结点*z 无左子树结点,只需重接其右子树
        z = z->rchild;
    }
    /**------------------------- 将p所指的子树挂接到其双亲结点*f相应的位置 -------------------------*/
    if (!f)  //被删除结点为根结点
        T = z;
    else if (q == f->lchild)
        f->lchild = z; //挂接到*f的左子树位置
    else
        f->rchild = z; //挂接到*f的右子树位置
    delete q;

}

Crear operación

La operación de creación del árbol de clasificación binaria comienza desde un árbol de clasificación binario vacío. No se ingresa ningún nodo. Después de la operación de búsqueda, el nuevo nodo se inserta en la posición apropiada del árbol de clasificación binario actual.

Descripción del algoritmo:

① Inicialice el árbol de clasificación binario T en un árbol vacío.
② Leer en un nodo cuya palabra clave es clave.
③ Si la clave de palabra clave leída no es la marca final de entrada, se realizan las siguientes operaciones en un bucle:

  • Inserte estos puntos en el árbol de clasificación binario T;
  • Leer en un nodo cuya palabra clave es clave.
void CreatBST(BSTree &T) {
    
    
    T = NULL;
    ElemType e;
    cin >> e;
    while (e.key != '\0') {
    
    
        InsertBST(T, e);
        cin >> e;
    }
}

Análisis de eficiencia de búsqueda

Supongo que te gusta

Origin blog.csdn.net/QQ657205470/article/details/127427327
Recomendado
Clasificación