Come trovare l'elemento più vicino ad un dato valore chiave in un albero binario di ricerca?

voti
15

Dato un BST con valori interi come tasti come faccio a trovare il nodo più vicino a quel tasto in un BST? La BST è rappresentato da un oggetto di nodi (Java). Più vicino sarà per esempio 4,5,9 e se la chiave è 6 tornerà 5 ..

È pubblicato 02/06/2011 alle 01:50
fonte dall'utente
In altre lingue...                            


11 risposte

voti
-1

La soluzione più semplice è quella di ricorsione vostro albero da quando

  • a trovare l'elemento
  • si raggiunge una foglia. Questo caso si dovrebbe fare un paio di confronto per determinare se il valore più vicino è la foglia, o il genitore della foglia.

Fino a voi l'implementazione.

Risposto il 02/06/2011 a 02:02
fonte dall'utente

voti
18

Traverse l'albero come si farebbe per trovare l'elemento. Mentre fate che registrano il valore che più si avvicina alla propria chiave. Ora, quando non avete trovato un nodo per la chiave stessa restituire il valore registrato.

Quindi, se stavate cercando la chiave 3nel seguente albero si finirebbe sul nodo 6senza trovare una corrispondenza, ma il vostro valore registrato saresti 2dato che questa era la chiave più vicina di tutti i nodi che si era attraversati ( 2, 7, 6).

                 2
              1      7
                   6   8
Risposto il 02/06/2011 a 02:03
fonte dall'utente

voti
11

Traverse prende O (n). Possiamo procedere in alto-basso? in questo modo il codice ricorsivo:

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;
}
Risposto il 08/06/2011 a 09:41
fonte dall'utente

voti
8

Si può essere risolto in O (log * n *) tempo.

  • Se il valore di un nodo è uguale al valore dato, è il nodo più vicino;
  • Se il valore di un nodo è maggiore del valore dato, passare al figlio sinistro;
  • Se il valore in un nodo è inferiore al valore dato, passare al figlio destro.

L'algoritmo può essere implementato con il seguente codice 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;
}

Si può visitare il mio blog per maggiori dettagli.

Risposto il 14/03/2013 a 03:19
fonte dall'utente

voti
0

Questo può essere fatto utilizzando una coda e un ArrayList. Coda sarà utilizzato per eseguire una ricerca in ampiezza sull'albero. ArrayList verrà utilizzata per memorizzare l'elemento dell'albero in ampiezza primo ordine. Ecco il codice per implementare lo stesso

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;
}
Risposto il 15/01/2014 a 14:06
fonte dall'utente

voti
2

Il problema con l'approccio "ha lasciato l'attraversamento a destra e trovare il più vicino" è che dipende sopra la sequenza in cui gli elementi sono stati inseriti per creare BST. Se si cerca 11 per la sequenza BST 22, 15, 16, 6,14,3,1,90, il metodo sopra restituirà 15 mentre la risposta corretta è 14. L'unico metodo dovrebbe usare ricorsione per attraversare tutti i nodi, tornando quello più vicino come il risultato della funzione ricorsiva. Questo ci darà il valore più vicino

Risposto il 02/06/2014 a 18:02
fonte dall'utente

voti
9

Ecco una soluzione ricorsiva in 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)
Risposto il 21/06/2014 a 23:44
fonte dall'utente

voti
0
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);
    }

}
Risposto il 24/07/2016 a 05:45
fonte dall'utente

voti
0

Qui di seguito si lavora con diversi campioni che ho.

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;
}
Risposto il 04/02/2017 a 10:10
fonte dall'utente

voti
0

Ecco il codice Java completo per trovare l'elemento più vicino in 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);
                }
            }

        }
Risposto il 11/06/2018 a 20:33
fonte dall'utente

voti
0

Ecco la soluzione di lavoro in Java che utilizza le caratteristiche di BST e integer aggiuntivo per memorizzare differenza minima

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);
            }
        }
    }

Tempo di esecuzione complessità - O (log N)

tempo di complessità spaziale - O (1)

Risposto il 08/09/2018 a 18:23
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more