Jak najít nejbližší prvek pro danou hodnotu klíče v binárním vyhledávacím stromu?

hlasů
15

Vzhledem k tomu, BST s celočíselné hodnoty jako klíče Jak najdu nejbližší uzlu ke klíči v BST? BST je reprezentován pomocí objektu uzlů (Java). Nejbližší bude pro např 4,5,9 a zda se tlačítko 6 vrátí 5 ..

Položena 02/06/2011 v 01:50
zdroj uživatelem
V jiných jazycích...                            


11 odpovědí

hlasů
-1

Nejjednodušším řešením je recurse svůj strom od té doby, kdy

  • najdete prvek
  • dostanete list. Tento případ je třeba provést několik porovnání určit, zda je nejbližší hodnota je list nebo rodič listu.

Až vás implementace.

Odpovězeno 02/06/2011 v 02:02
zdroj uživatelem

hlasů
18

Traverse stromu, jako byste najít element. Zatímco vy ten rekord na hodnotu, která je nejblíže ke svému klíči. Nyní, když jste nenašli uzel pro klíč sám vrátit zaznamenanou hodnotu.

Takže pokud jste hledali klíč 3v následujícím stromu byste skončit na uzlu 6bez nálezu zápas, ale vaše zaznamenané hodnoty by bylo 2, protože to bylo nejblíže klíč všech uzlů, které jste měli, jimiž projíždí ( 2, 7, 6).

                 2
              1      7
                   6   8
Odpovězeno 02/06/2011 v 02:03
zdroj uživatelem

hlasů
11

Traverza se O (n). Můžeme postupovat to v horním dnu? jako je tento rekurzivní kód:

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;
}
Odpovězeno 08/06/2011 v 09:41
zdroj uživatelem

hlasů
8

To může být řešen v O (log * n *) čas.

  • Je-li hodnota v uzlu je stejná jako danou hodnotu, je to nejbližší uzel;
  • Je-li hodnota v uzlu je větší než daná hodnota, přesunout do levého dítěte;
  • Je-li hodnota v uzlu je menší než daná hodnota, přesun do pravého dítěte.

Tento algoritmus může být implementován s následujícím kódem 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;
}

Můžete navštívit můj blog pro více informací.

Odpovězeno 14/03/2013 v 03:19
zdroj uživatelem

hlasů
0

To lze provést pomocí fronty a ArrayList. Fronta bude použit k provedení prohledávání do šířky na stromě. ArrayList bude použit pro uložení prvku stromu do šířky prvního řádu. Zde je kód implementovat stejné

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;
}
Odpovězeno 15/01/2014 v 14:06
zdroj uživatelem

hlasů
2

Problém s přístupem „vlevo vpravo traversal a najít nejbližší“ je, že záleží nad pořadí, v jakém byly zadány prvky vytvořit BST. Pokud budeme hledat 11 pro BST sekvence 22, 15, 16, 6,14,3,1,90, bude výše uvedený způsob vrátí 15, zatímco správná odpověď je 14. Jedinou metodou, by měl být pomocí rekurze projít všechny uzly, vrácení nejbližší jeden jako výsledek rekurzivní funkce. To nám dá nejbližší hodnotu

Odpovězeno 02/06/2014 v 18:02
zdroj uživatelem

hlasů
9

Zde je rekurzivní řešení v jazyce 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)
Odpovězeno 21/06/2014 v 23:44
zdroj uživatelem

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

}
Odpovězeno 24/07/2016 v 05:45
zdroj uživatelem

hlasů
0

Níže se pracuje s různými vzorky, které mám.

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;
}
Odpovězeno 04/02/2017 v 10:10
zdroj uživatelem

hlasů
0

Zde je plná Java kód najít nejbližší prvek v 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);
                }
            }

        }
Odpovězeno 11/06/2018 v 20:33
zdroj uživatelem

hlasů
0

Zde je pracovní roztok v jazyce Java, který využívá vlastnosti BST a další celé číslo k uložení minimálního rozdílu

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

Run time složitost - O (LOGN)

Doba prostor složitost - O (1)

Odpovězeno 08/09/2018 v 18:23
zdroj uživatelem

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