Dado un BST con valores enteros como claves ¿Cómo puedo encontrar el nodo más cercano a esa tecla en un BST? El BST se representa usando un objeto de nodos (Java). Habrá más cercano para, por ejemplo 4,5,9 y si la clave es 6 se volverá 5 ..
¿Cómo encontrar el elemento más cercano a un valor clave dada en un árbol binario de búsqueda?
La solución más fácil es recursivo su árbol ya que cuando
- a encontrar el elemento
- llegar a una hoja. Este caso se debe hacer un par de comparación para determinar si el valor más cercano es la hoja o el padre de la hoja.
Hasta que la puesta en práctica.
Recorrer el árbol como si se tratara de encontrar el elemento. Mientras que usted hace ese registro el valor que más se aproxime a su clave. Ahora, cuando usted no ha encontrado un nodo para la propia llave devolver el valor registrado.
Así que si estás buscando la llave 3en el siguiente árbol que terminaría en el nodo 6sin encontrar un partido, pero su valor registrado estaría 2ya que esta fue la clave más cercano de todos los nodos que había atravesado ( 2, 7, 6).
2
1 7
6 8
Traverse toma tiempo O (n). Podemos proceder en la parte superior-inferior? como el código recursivo:
Tnode * closestBST(Tnode * root, int val){
if(root->val == val)
return root;
if(val < root->val){
if(!root->left)
return root;
Tnode * p = closestBST(root->left, val);
return abs(p->val-val) > abs(root->val-val) ? root : p;
}else{
if(!root->right)
return root;
Tnode * p = closestBST(root->right, val);
return abs(p->val-val) > abs(root->val-val) ? root : p;
}
return null;
}
Se puede resolverse en O (log * n *) tiempo.
- Si el valor de un nodo es igual que el valor dado, es el nodo más cercano;
- Si el valor en un nodo es mayor que el valor dado, pasar a la hijo izquierdo;
- Si el valor de un nodo es menor que el valor dado, pasar al hijo derecho.
El algoritmo puede ser implementado con el siguiente código de C ++:
BinaryTreeNode* getClosestNode(BinaryTreeNode* pRoot, int value)
{
BinaryTreeNode* pClosest = NULL;
int minDistance = 0x7FFFFFFF;
BinaryTreeNode* pNode = pRoot;
while(pNode != NULL){
int distance = abs(pNode->m_nValue - value);
if(distance < minDistance){
minDistance = distance;
pClosest = pNode;
}
if(distance == 0)
break;
if(pNode->m_nValue > value)
pNode = pNode->m_pLeft;
else if(pNode->m_nValue < value)
pNode = pNode->m_pRight;
}
return pClosest;
}
Usted puede visitar mi blog para más detalles.
Esto se puede hacer usando una cola y un ArrayList. Cola se utiliza para realizar una búsqueda en anchura en el árbol. ArrayList se utiliza para almacenar el elemento del árbol en orden de amplitud primero. Aquí está el código para implementar la misma
Queue queue = new LinkedList();
ArrayList list = new ArrayList();
int i =0;
public Node findNextRightNode(Node root,int key)
{
System.out.print("The breadth first search on Tree : \t");
if(root == null)
return null;
queue.clear();
queue.add(root);
while(!queue.isEmpty() )
{
Node node = (Node)queue.remove();
System.out.print(node.data + " ");
list.add(node);
if(node.left != null) queue.add(node.left);
if(node.right !=null) queue.add(node.right);
}
Iterator iter = list.iterator();
while(iter.hasNext())
{
if(((Node)iter.next()).data == key)
{
return ((Node)iter.next());
}
}
return null;
}
El problema con el enfoque "a la izquierda de recorrido adecuado y encontrar el más cercano" es que depende más de la secuencia en la que se introdujeron elementos para crear BST. Si buscamos 11 para la secuencia de BST 22, 15, 16, 6,14,3,1,90, el método anterior devolverá 15 mientras que la respuesta correcta es 14. El único método debería estar utilizando la recursividad de atravesar todos los nodos, volviendo el más próximo como el resultado de la función recursiva. Esto nos dará el valor más cercano
Aquí hay una solución recursiva en Python:
def searchForClosestNodeHelper(root, val, closestNode):
if root is None:
return closestNode
if root.val == val:
return root
if closestNode is None or abs(root.val - val) < abs(closestNode.val - val):
closestNode = root
if val < root.val:
return searchForClosestNodeHelper(root.left, val, closestNode)
else:
return searchForClosestNodeHelper(root.right, val, closestNode)
def searchForClosestNode(root, val):
return searchForClosestNodeHelper(root, val, None)
void closestNode(Node root, int k , Node result) {
if(root == null)
{
return; //currently result is null , so it will be the result
}
if(result == null || Math.abs(root.data - k) < Math.abs(result.data - k) )
{
result == root;
}
if(k < root.data)
{
closestNode(root.left, k, result)
}
else
{
closestNode(root.right, k, result);
}
}
A continuación se trabaja con diferentes muestras que tengo.
public Node findNearest(Node root, int k) {
if (root == null) {
return null;
}
int minDiff = 0;
Node minAt = root;
minDiff = Math.abs(k - root.data);
while (root != null) {
if (k == root.data) {
return root;
}
if (k < root.data) {
minAt = updateMin(root, k, minDiff, minAt);
root = root.left;
} else if (k > root.data) {
minAt = updateMin(root, k, minDiff, minAt);
root = root.right;
}
}
return minAt;
}
private Node updateMin(Node root, int k, int minDiff, Node minAt) {
int curDif;
curDif = Math.abs(k - root.data);
if (curDif < minDiff) {
minAt = root;
}
return minAt;
}
Aquí está el código Java completo para encontrar el elemento más cercano en un BST.
package binarytree;
class BSTNode {
BSTNode left,right;
int data;
public BSTNode(int data) {
this.data = data;
this.left = this.right = null;
}
}
class BST {
BSTNode root;
public static BST createBST() {
BST bst = new BST();
bst.root = new BSTNode(9);
bst.root.left = new BSTNode(4);
bst.root.right = new BSTNode(17);
bst.root.left.left = new BSTNode(3);
bst.root.left.right= new BSTNode(6);
bst.root.left.right.left= new BSTNode(5);
bst.root.left.right.right= new BSTNode(7);
bst.root.right.right = new BSTNode(22);
bst.root.right.right.left = new BSTNode(20);
return bst;
}
}
public class ClosestElementInBST {
public static void main(String[] args) {
BST bst = BST.createBST();
int target = 18;
BSTNode currentClosest = null;
BSTNode closestNode = findClosestElement(bst.root, target, currentClosest);
if(closestNode != null) {
System.out.println("Found closest node: " + closestNode.data);
}
else {
System.out.println("Couldn't find closest node.");
}
}
private static BSTNode findClosestElement(BSTNode node, int target, BSTNode currentClosest) {
if(node == null) return currentClosest;
if(currentClosest == null ||
(currentClosest != null && (Math.abs(currentClosest.data - target) > Math.abs(node.data - target)))) {
currentClosest = node;
}
if(node.data == target) return node;
else if(target < node.data) {
return findClosestElement(node.left, target, currentClosest);
}
else { //target > node.data
currentClosest = node;
return findClosestElement(node.right, target, currentClosest);
}
}
}
Aquí está la solución de trabajo en java que utiliza las características de BST y número entero adicional para almacenar mínima diferencia
public class ClosestValueBinaryTree {
static int closestValue;
public static void closestValueBST(Node22 node, int target) {
if (node == null) {
return;
}
if (node.data - target == 0) {
closestValue = node.data;
return;
}
if (Math.abs(node.data - target) < Math.abs(closestValue - target)) {
closestValue = node.data;
}
if (node.data - target < 0) {
closestValueBST(node.right, target);
} else {
closestValueBST(node.left, target);
}
}
}
Tiempo de ejecución complejidad - O (logN)
espacio tiempo complejidad - O (1)













