Algorithm 如何在二叉搜索树中找到与给定键值最近的元素?
给定一个以整数值作为键的bst,如何在bst中找到与该键最近的节点?Algorithm 如何在二叉搜索树中找到与给定键值最近的元素?,algorithm,data-structures,binary-search-tree,Algorithm,Data Structures,Binary Search Tree,给定一个以整数值作为键的bst,如何在bst中找到与该键最近的节点? BST使用节点对象(Java)表示。最接近的是eg 4、5、9,如果键为6,则返回5 像查找元素一样遍历树。执行此操作时,请记录最接近键的值。现在,如果找不到键本身的节点,请返回记录的值 因此,如果您在下面的树中查找键3,您将在节点6上结束,但没有找到匹配项,但是您记录的值将是2,因为这是您所遍历的所有节点中最近的键(2,7,6) 遍历需要O(n)个时间。我们可以从上到下进行吗?像这样的递归代码: Tnode * closes
BST使用节点对象(Java)表示。最接近的是eg 4、5、9,如果键为6,则返回5 像查找元素一样遍历树。执行此操作时,请记录最接近键的值。现在,如果找不到键本身的节点,请返回记录的值 因此,如果您在下面的树中查找键
3
,您将在节点6
上结束,但没有找到匹配项,但是您记录的值将是2
,因为这是您所遍历的所有节点中最近的键(2
,7
,6
)
遍历需要O(n)个时间。我们可以从上到下进行吗?像这样的递归代码:
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;
}
Tnode*closestBST(Tnode*root,int-val){
如果(根->val==val)
返回根;
如果(valval){
如果(!root->left)
返回根;
Tnode*p=closestBST(根->左,val);
返回abs(p->val)>abs(root->val)→root:p;
}否则{
如果(!root->right)
返回根;
Tnode*p=closestBST(根->右,val);
返回abs(p->val)>abs(root->val)→root:p;
}
返回null;
}
它可以在O(log*n*)时间内解决
- 如果节点中的值与给定值相同,则该节点是最近的节点李>
- 如果节点中的值大于给定值,则移动到左侧子节点李>
- 如果节点中的值小于给定值,请移动到右侧子节点
该算法可以用以下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;
}
BinaryTreeNode*getClosestNode(BinaryTreeNode*pRoot,int值)
{
二进制树节点*pClosest=NULL;
int minDistance=0x7FFFFFFF;
二元树节点*pNode=pRoot;
while(pNode!=NULL){
int distance=abs(pNode->m_nValue-value);
if(距离<距离){
距离=距离;
pClosest=pNode;
}
如果(距离==0)
打破
如果(pNode->m\u nValue>value)
pNode=pNode->m_pLeft;
else if(pNode->m\u nValuem_pRight;
}
返回pClosest;
}
您可以访问以了解更多详细信息。这可以使用队列和ArrayList来完成。 队列将用于在树上执行广度优先搜索。 ArrayList将用于按宽度优先顺序存储树的元素。 下面是实现相同功能的代码
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;
}
“左右遍历并查找最近的”方法的问题在于,它取决于创建BST时输入元素的顺序。如果我们搜索11以查找BST序列22、15、16、6、14、3、1、90,上述方法将返回15,而正确答案为14。
唯一的方法应该是使用递归遍历所有节点,将最近的节点作为递归函数的结果返回。这将为我们提供最接近的值这是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)
def searchforclosestnodehelp(根、val、closestNode):
如果root为None:
返回closestNode
如果root.val==val:
返回根
如果closestNode为None或abs(root.val-val)
void closestNode(节点根、int k、节点结果){
if(root==null)
{
return;//当前结果为null,因此将是结果
}
if(result==null | | Math.abs(root.data-k)
下面的一个示例适用于我拥有的不同示例
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;
}
公共节点findNearest(节点根,int k){
if(root==null){
返回null;
}
int minDiff=0;
节点minAt=根;
minDiff=Math.abs(k-root.data);
while(root!=null){
if(k==root.data){
返回根;
}
if(k<根数据){
minAt=updateMin(根,k,minDiff,minAt);
root=root.left;
}else if(k>root.data){
minAt=updateMin(根,k,minDiff,minAt);
root=root.right;
}
}
返回minAt;
}
私有节点updateMin(节点根、int k、int minDiff、节点minAt){
int curDif;
curDif=Math.abs(k-root.data);
如果(curDif
以下是在BST中查找最近元素的完整Java代码
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);
}
}
}
包二进制树;
类节点{
左,右;
int数据;
公共节点(int数据){
这个数据=数据;
this.left=this.right=null;
}
}
BST级{
节点根;
公共静态BST createBST(){
BST BST=新的BST();
bst.root=新的BSTNode(9);
bst.root.left=新的BSTNode(4);
bst.root.right=新的BSTNode(17);
bst.root.left.left=新的BSTNode(3);
bst.root.left.right=新的BSTNode(6);
bst.root.left.right.left=新的BSTNode(5);
bst.root.left.right.right=新的BSTNode(7);
bst.root.right.right=新的BSTNode(22);
bst.root.right.right.left=新的BSTNode(20);
返回bst;
}
}
公共类ClosestElementInBST{
公众的
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;
}
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);
}
}
}
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);
}
}
}