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 ..
Jak najít nejbližší prvek pro danou hodnotu klíče v binárním vyhledávacím stromu?
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.
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
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;
}
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í.
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;
}
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
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)
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);
}
}
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;
}
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);
}
}
}
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)













