Având în vedere o BST cu valori întregi ca chei cum pot găsi cel mai apropiat nod la acea cheie într-un BST? BST este reprezentat folosind un obiect de noduri (Java). Cea mai apropiată va fi de exemplu 4,5,9 și dacă cheia este 6 se va reveni 5 ..
Cum de a găsi cel mai apropiat element cheie la o valoare dată într-un arbore binar de căutare?
Cea mai simplă soluție este de a recurse copac, deoarece atunci când
- găsiți elementul
- ajungeți la o frunză. Acest caz ar trebui să facă un cuplu de comparație pentru a determina dacă cea mai apropiată valoare este frunza sau părintele a frunzei.
Până să te punerea în aplicare.
Traverse copac ca și cum ați găsi elementul. În timp ce faci asta înregistra valoarea care este cea mai apropiată de cheia. Acum, când nu a găsit un nod pentru cheia se returna valoarea înregistrată.
Deci , dacă ați fost în căutarea pentru cheia 3în următorul copac v - ar ajunge pe nodul 6fără a găsi o potrivire , dar valoarea dvs. înregistrată ar fi , 2deoarece aceasta a fost cea mai apropiată cheia de toate nodurile pe care le - a traversat ( 2, 7, 6).
2
1 7
6 8
Traverse ia O (n). O putem proceda în sus-jos? ca acest cod recursiv:
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;
}
Ea poate fi rezolvată în O (log * n *) timp.
- Dacă valoarea într-un nod este aceeași ca și valoarea dată, este cel mai apropiat nod;
- Dacă valoarea într-un nod este mai mare decât valoarea dată, trece la copilul din stânga;
- Dacă valoarea într-un nod este mai mică decât valoarea dată, trece la copilul din dreapta.
Algoritmul poate fi implementat cu următorul cod 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;
}
Puteti vizita blog - ul meu pentru mai multe detalii.
Acest lucru se poate face folosind o coadă și un ArrayList. Coadă va fi utilizat pentru a efectua o primă căutare lățime pe copac. ArrayList va fi folosit pentru a stoca elementul de copac în lățime ordine mai întâi. Aici este codul pentru a pune în aplicare aceleași
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;
}
Problema cu abordarea „stânga parcurgeri dreapta și de a găsi cel mai aproape“ este că depinde peste secvența în care au fost introduse elemente pentru a crea BST. Dacă vom căuta 11 pentru secvența BST 22, 15, 16, 6,14,3,1,90, metoda de mai sus va returna 15, în timp ce răspunsul corect este 14. Singura metodă ar trebui să fie folosind recursie pentru a traversa toate nodurile, revenind cel mai apropiat ca rezultat al funcției recursive. Acest lucru ne va da cea mai apropiată valoare
Iată o soluție recursiv în 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);
}
}
Mai jos se lucrează cu diferite probe pe care le am.
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;
}
Aici este cod complet Java pentru a găsi cel mai apropiat element într-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);
}
}
}
Aici este soluția de lucru în Java care utilizează caracteristicile BST și întreg suplimentar pentru a stoca o diferență minimă
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 complexitate - O (LOGN)
spațiu timp de complexitate - O (1)













