¿Cómo se implementa un árbol KD bidimensional en C ++?

A continuación se muestra el código en implementación de C ++ en árboles AVL y árboles Kd

PARA OBTENER MÁS CÓDIGOS QUE PUEDE VISITAR A las tareas de programación

Implemente AVL-Trees con operación de inserción, eliminación y kth min. Implemente Kd-Trees (k = 2,3) con la operación de inserción, eliminación y búsqueda.

// El código de AVLtree.cpp sigue …

#include “AVLTree.h”

AVLTree :: AVLTree ()

{

root_ = NULL;

}

AVLTree :: ~ AVLTree ()

{

}

AVLTree vacío :: insert (clave int)

{

root_ = (AVLTreeNode *) insert (root_, key);

}

IAVLTreeNode * AVLTree :: insert (AVLTreeNode * nodo, clave int)

{

/ * 1. Realizar la rotación BST normal * /

if (nodo == NULL) {

AVLTreeNode * temp = new AVLTreeNode ();

temp-> setKey (clave);

temp-> setLeft (NULL);

temp-> setRight (NULL);

raíz_ = temp;

temperatura de retorno;

}

if (clave getKey ())

nodo-> setLeft (insert ((AVLTreeNode *) nodo-> getLeft (), clave));

más

nodo-> setRight (insert ((AVLTreeNode *) nodo-> getRight (), clave));

/ * 2. Actualizar la altura de este nodo ancestro * /

nodo-> setHeight (max (height ((AVLTreeNode *) node-> getLeft ()), height ((AVLTreeNode *) node-> getRight ())) + 1);

/ * 3. Obtenga el factor de equilibrio de este nodo ancestro para verificar si

este nodo se desequilibró * /

int balance = getBalance (nodo);

// Si este nodo se desequilibra, entonces hay 4 casos

// Caso izquierdo izquierdo

if (balance> 1 && key getLeft () -> getKey ())

return rightRotate (nodo);

// Derecha Derecha Caso

if (balance nodo-> getRight () -> getKey ())

return leftRotate (nodo);

// Caso izquierdo derecho

if (balance> 1 && key> nodo-> getLeft () -> getKey ())

{

nodo-> setLeft (leftRotate ((AVLTreeNode *) nodo-> getLeft ()));

return rightRotate (nodo);

}

// Caso derecho e izquierdo

if (balance <-1 && key getRight () -> getKey ())

{

nodo-> setRight (rightRotate ((AVLTreeNode *) nodo-> getRight ()));

return leftRotate (nodo);

}

/ * devuelve el puntero de nodo (sin cambios) * /

nodo de retorno;

}

IAVLTreeNode * AVLTree :: rightRotate (AVLTreeNode * y)

{

AVLTreeNode * x = (AVLTreeNode *) y-> getLeft ();

AVLTreeNode * T2 = (AVLTreeNode *) x-> getRight ();

// Realizar rotación

x-> setRight (y);

y-> setLeft (T2);

// Actualizar alturas

y-> setHeight (max (height ((AVLTreeNode *) y-> getLeft ()), height ((AVLTreeNode *) y-> getRight ())) + 1);

x-> setHeight (max (height ((AVLTreeNode *) x-> getLeft ()), height ((AVLTreeNode *) x-> getRight ())) + 1);

// Devuelve nueva raíz

volver x;

}

// Una función de utilidad para rotar a la izquierda el subárbol enraizado con x

// Ver el diagrama dado arriba.

IAVLTreeNode * AVLTree :: leftRotate (AVLTreeNode * x)

{

AVLTreeNode * y = (AVLTreeNode *) x-> getRight ();

AVLTreeNode * T2 = (AVLTreeNode *) y-> getLeft ();

// Realizar rotación

y-> setLeft (x);

x-> setRight (T2);

// Actualizar alturas

x-> setHeight (max (height ((AVLTreeNode *) x-> getLeft ()), height ((AVLTreeNode *) x-> getRight ())) + 1);

y-> setHeight (max (height ((AVLTreeNode *) y-> getLeft ()), height ((AVLTreeNode *) y-> getRight ())) + 1);

// Devuelve nueva raíz

volver y;

}

// Obtener el factor de equilibrio del nodo N

int AVLTree :: getBalance (AVLTreeNode * N)

{

si (N == NULL)

devuelve 0;

return height ((AVLTreeNode *) N-> getLeft ()) – height ((AVLTreeNode *) N-> getRight ());

}

int AVLTree :: height (AVLTreeNode * N)

{

si (N == NULL)

volver -1;

return N-> getHeight ();

}

// Una función de utilidad para obtener un máximo de dos enteros

int AVLTree :: max (int a, int b)

{

volver (a> b)? a: b;

}

AVLTree vacío :: eliminar (clave int)

{

root_ = deleteNode (root_, clave);

}

AVLTreeNode * AVLTree :: deleteNode (AVLTreeNode * root, int key)

{

// PASO 1: REALIZA EL ESTÁNDAR BST BORRAR

if (raíz == NULL)

volver root;

// Si la clave que se va a eliminar es más pequeña que la clave de la raíz,

// luego se encuentra en el subárbol izquierdo

if (clave getKey ())

root-> setLeft (deleteNode ((AVLTreeNode *) root-> getLeft (), key));

// Si la clave que se va a eliminar es mayor que la clave de la raíz,

// entonces se encuentra en el subárbol derecho

de lo contrario if (key> root-> getKey ())

root-> setRight (deleteNode ((AVLTreeNode *) root-> getRight (), key));

// si la clave es la misma que la raíz, entonces este es el nodo

// para ser eliminado

más

{

// nodo con un solo hijo o sin hijo

if ((root-> getLeft () == NULL) || (root-> getRight () == NULL))

{

AVLTreeNode * temp = (AVLTreeNode *) root-> getLeft ()? (AVLTreeNode *) root-> getLeft (): (AVLTreeNode *) root-> getRight ();

// Sin caso hijo

if (temp == NULL)

{

temp = raíz;

raíz = NULL;

}

más // caso de un niño

* raíz = * temp; // Copie el contenido del niño no vacío

libre (temp);

}

más

{

// nodo con dos hijos: Obtener el sucesor de pedido (el más pequeño

// en el subárbol derecho)

AVLTreeNode * temp = minValueNode ((AVLTreeNode *) root-> getRight ());

// Copie los datos del sucesor del pedido en este nodo

root-> setKey (temp-> getKey ());

// Eliminar el sucesor de pedido

root-> setRight (deleteNode ((AVLTreeNode *) root-> getRight (), temp-> getKey ()));

}

}

// Si el árbol tenía solo un nodo, entonces regresar

if (raíz == NULL)

volver root;

// PASO 2: ACTUALIZAR LA ALTURA DEL NODO ACTUAL

root-> setHeight (max (height ((AVLTreeNode *) root-> getLeft ()), height ((AVLTreeNode *) root-> getRight ())) + 1);

// PASO 3: OBTENGA EL FACTOR DE EQUILIBRIO DE ESTE NODO (para verificar si

// este nodo se desequilibró)

int balance = getBalance (root);

// Si este nodo se desequilibra, entonces hay 4 casos

// Caso izquierdo izquierdo

if (balance> 1 && getBalance ((AVLTreeNode *) root-> getLeft ())> = 0)

return (AVLTreeNode *) rightRotate (root);

// Caso izquierdo derecho

if (balance> 1 && getBalance ((AVLTreeNode *) root-> getLeft ()) <0)

{

root-> setLeft (leftRotate ((AVLTreeNode *) root-> getLeft ()));

return (AVLTreeNode *) rightRotate (root);

}

// Derecha Derecha Caso

if (balance getRight ()) <= 0)

return (AVLTreeNode *) leftRotate (root);

// Caso derecho e izquierdo

if (balance getRight ())> 0)

{

root-> setRight (rightRotate ((AVLTreeNode *) root-> getRight ()));

return (AVLTreeNode *) leftRotate (root);

}

volver root;

}

AVLTreeNode * AVLTree :: minValueNode (nodo AVLTreeNode *)

{

AVLTreeNode * current = node;

/ * recorrer hacia abajo para encontrar la hoja más a la izquierda * /

while (current-> getLeft ()! = NULL)

current = (AVLTreeNode *) current-> getLeft ();

corriente de retorno;

}

int AVLTree :: kthMin (int k)

{

int input = k + 1;

int cuenta = 0;

int val = 0;

val = KthElement (root_, count, input);

si (val! = 0)

retorno val;

}

int AVLTree :: KthElement (IAVLTreeNode * root, int & count, int k)

{

int int res;

si (raíz)

{

KthElement (root-> getLeft (), count, k);

recuento ++;

si (cuenta == k)

{

res = root-> getKey ();

}

KthElement (root-> getRight (), count, k);

}

volver res;

}

IAVLTreeNode * AVLTree :: getRoot ()

{

volver root_;

}

IAVLTreeNode * AVLTree :: createNode (clave int)

{

AVLTreeNode * temp = new AVLTreeNode ();

temp-> setKey (clave);

temp-> setLeft (NULL);

temp-> setRight (NULL);

temperatura de retorno;

}

// El código de KDtree.cpp sigue …

#include “KdTree.h”

KdTree :: KdTree ()

{

}

KdTree :: ~ KdTree ()

{

}

vacío KdTree :: setRoot (raíz IKdNode *)

{

}

IKdNode * KdTree :: getRoot ()

{

devuelve NULL;

}

vacío KdTree :: setDim (int dim)

{

}

int KdTree :: getDim ()

{

devuelve 0;

}

anular KdTree :: insert (std :: vector punto)

{

}

bool KdTree :: search (std :: vector point)

{

falso retorno;

}

bool KdTree :: remove (std :: vector punto)

{

falso retorno;

}

IKdNode * KdTree ::arestNeighbor (std :: vector point)

{

devuelve NULL;

}

Puede usar matrices para representar puntos. El árbol KD es binario, por lo que podría usar una matriz: el hijo izquierdo del nodo x vive en la posición 2x ​​y el hijo derecho vive en la posición 2x ​​+ 1. Use la mediana para seleccionar el valor de división. La inserción es recursiva; Mantenga el código corto.

Puede consultar mi repositorio de Github donde implementé un árbol bidimensional en C ++.

Aquí está el repositorio: KorayGocmen / kdTree

Con suerte, esto aclarará sus preguntas

More Interesting

¿Cuál es el mejor algoritmo para calcular la cantidad de números primos?

¿Qué es un algoritmo eficiente para el agrupamiento k-means donde k es 2 y la dimensión es una, con o sin pesos?

Cómo saber cuándo usar .add o .put para agregar a una matriz en Java

¿Por qué las funciones recursivas son tan difíciles de entender?

Cómo resolver el problema SPOJ XORROUND

¿Cuántas repeticiones del algoritmo L, U, R, D en un cubo de Rubik se necesitarían para revertir el cubo a su permutación original?

¿Cuál es la forma más fácil de demostrar que si la intersección de 2 rutas es un gráfico conectado, entonces la unión de las 2 rutas tiene al menos un circuito?

¿Es correcto mi nuevo estado de ánimo? Ingresé a la programación desde un punto de vista de programación algorítmica y, como tal, tengo una inclinación a querer saber cómo funcionan las cosas debajo. Pero ahora, después de un tiempo en el mundo de los desarrolladores, finalmente tengo que darme cuenta de que se trata menos de eso. ¿Lo que usted dice?

¿Por qué soy tan dinámico?

¿Por qué prácticamente todos los algoritmos de ascensor son tan ineficientes y cuáles son las razones por las que aún no se han optimizado?

¿Debo tomar un curso de Matemática discreta para comprender mejor las estructuras de datos?

¿Alguien puede ayudarme a dibujar un árbol de recursión para la ecuación [matemáticas] T (n) = T (n-2) + n [/ matemáticas]?

¿Qué es una lista circular vinculada en Java?

¿Qué hay de malo con este código básico de Python?

¿De dónde provienen los datos de entrenamiento para analizar las consultas en inglés en un árbol para Facebook GraphSearch?