Jak znaleźć najbliższy elementu do danej wartości klucza w wyszukiwaniu binarnym drzewie?

głosy
15

Biorąc pod uwagę bst z liczb całkowitych jako klucze, jak mogę znaleźć najbliższy węzeł do tego klucza w BST? BST jest przedstawiony za pomocą obiektu węzłów (Java). Najbliżej będzie do np 4,5,9 i jeśli klucz jest 6 powróci 5 ..

Utwórz 02/06/2011 o 01:50
źródło użytkownik
W innych językach...                            


11 odpowiedzi

głosy
-1

Najprostszym rozwiązaniem jest przeszukanie drzewa od kiedy

  • znaleźć element
  • dojdziesz liściu. Przypadek ten należy zrobić kilka porównaniu do ustalenia, czy wartość jest najbliższa liść lub rodzic z liścia.

Do ciebie realizacja.

Odpowiedział 02/06/2011 o 02:02
źródło użytkownik

głosy
18

Traverse drzewa tak jak znaleźć element. Podczas wykonywania tego rekordu wartości, która jest najbliżej klucza. Teraz, kiedy nie znaleźć węzeł klucza sama powrócić nagrany wartość.

Więc jeśli szukali klucza 3w następnym drzewem by skończyć się na węźle 6bez znalezienia dopasowania, ale swoją wartość będzie rejestrowane 2, ponieważ był to najbliższy kluczowy wszystkich węzłów, które trzeba było (które przechodzi 2, 7, 6).

                 2
              1      7
                   6   8
Odpowiedział 02/06/2011 o 02:03
źródło użytkownik

głosy
11

Przesuw odbywa O (n). Możemy kontynuować to w górnym dnie? jak tego kodu rekurencyjnego:

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;
}
Odpowiedział 08/06/2011 o 09:41
źródło użytkownik

głosy
8

To może być rozwiązany w O (log * n *) czas.

  • Jeśli wartość w węźle jest taka sama jak podana wartość, to najbliższy węzeł;
  • Jeśli wartość w węźle jest większa niż podana wartość, przesuń w lewo dziecka;
  • Jeśli wartość w węźle jest mniejsza od podanej wartości, przejść do prawego dziecka.

Algorytm może być realizowane za pomocą następującego kodu 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;
}

Możesz odwiedzić mój blog po więcej szczegółów.

Odpowiedział 14/03/2013 o 03:19
źródło użytkownik

głosy
0

Można to zrobić za pomocą Queue i ArrayList. Kolejka będą wykorzystywane do wykonywania przeszukiwanie wszerz na drzewie. ArrayList będą wykorzystywane do przechowywania elementu drzewa wszerz pierwszej kolejności. Oto kod, aby wdrożyć takie same

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;
}
Odpowiedział 15/01/2014 o 14:06
źródło użytkownik

głosy
2

Problem z podejściem „left right przechodzenie i znalezienie najbliżej” jest to, że zależy na sekwencji, w której elementy zostały wprowadzone przy tworzeniu BST. Jeśli szukamy 11 dla sekwencji BST 22, 15, 16, 6,14,3,1,90, powyższa metoda zwróci 15, podczas gdy prawidłowa odpowiedź brzmi 14. Jedyna metoda powinna być za pomocą rekurencji przemierzać wszystkie węzły, zwracając baczną jeden jako wynik funkcji rekurencyjnej. To będzie nam najbliższą wartość

Odpowiedział 02/06/2014 o 18:02
źródło użytkownik

głosy
9

Oto rozwiązanie rekurencyjna w Pythonie:

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)
Odpowiedział 21/06/2014 o 23:44
źródło użytkownik

głosy
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);
    }

}
Odpowiedział 24/07/2016 o 05:45
źródło użytkownik

głosy
0

Poniżej jeden współpracuje z różnych próbek, które mam.

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;
}
Odpowiedział 04/02/2017 o 10:10
źródło użytkownik

głosy
0

Oto pełny kod Java, aby znaleźć najbliższy element w 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);
                }
            }

        }
Odpowiedział 11/06/2018 o 20:33
źródło użytkownik

głosy
0

Oto roztwór roboczy w Java, która wykorzystuje charakterystyki BST i dodatkowego całkowitej przechowywać minimalną różnicę

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

Czas pracy złożoność - O (logN)

Czas Przestrzeń złożoność - O (1)

Odpowiedział 08/09/2018 o 18:23
źródło użytkownik

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