📌  相关文章
📜  BST中两个节点之间的最短距离

📅  最后修改于: 2021-05-25 00:21:11             🧑  作者: Mango

给定一个二叉搜索树和其中的两个键。使用给定的两个键找到两个节点之间的距离。可以假定两个密钥都存在于BST中。

BST

例子:

Input:  Root of above tree
         a = 3, b = 9
Output: 4
Distance between 3 and 9 in 
above BST is 4.

Input: Root of above tree
         a = 9, b = 25
Output: 3
Distance between 9 and 25 in 
above BST is 3.

我们已经讨论了二叉树中两个节点之间的距离。该解决方案的时间复杂度为O(n)

在使用BST的情况下,我们可以更快地找到距离。我们从根开始,对于每个节点,我们都遵循以下步骤。

  1. 如果两个键都大于当前节点,则移至当前节点的右子级。
  2. 如果两个键都小于当前节点,则移至当前节点的左子节点。
  3. 如果一个键较小,而另一个键较大,则当前节点为两个节点的最低公共祖先(LCA)。我们从两个键中找到当前节点的距离,并返回这些距离的总和。
C++
// CPP program to find distance between
// two nodes in BST
#include 
using namespace std;
  
struct Node {
    struct Node* left, *right;
    int key;
};
  
struct Node* newNode(int key)
{
    struct Node* ptr = new Node;
    ptr->key = key;
    ptr->left = ptr->right = NULL;
    return ptr;
}
  
// Standard BST insert function
struct Node* insert(struct Node* root, int key)
{
    if (!root)
        root = newNode(key);
    else if (root->key > key)
        root->left = insert(root->left, key);
    else if (root->key < key)
        root->right = insert(root->right, key);
    return root;
}
  
// This function returns distance of x from
// root. This function assumes that x exists
// in BST and BST is not NULL.
int distanceFromRoot(struct Node* root, int x)
{
    if (root->key == x)
        return 0;
    else if (root->key > x)
        return 1 + distanceFromRoot(root->left, x);
    return 1 + distanceFromRoot(root->right, x);
}
  
// Returns minimum distance between a and b.
// This function assumes that a and b exist
// in BST.
int distanceBetween2(struct Node* root, int a, int b)
{
    if (!root)
        return 0;
  
    // Both keys lie in left
    if (root->key > a && root->key > b)
        return distanceBetween2(root->left, a, b);
  
    // Both keys lie in right
    if (root->key < a && root->key < b) // same path
        return distanceBetween2(root->right, a, b);
  
    // Lie in opposite directions (Root is
    // LCA of two nodes)
    if (root->key >= a && root->key <= b)
        return distanceFromRoot(root, a) + 
               distanceFromRoot(root, b);
}
  
// This function make sure that a is smaller
// than b before making a call to findDistWrapper()
int findDistWrapper(Node *root, int a, int b)
{
   if (a > b)
     swap(a, b);
   return distanceBetween2(root, a, b);   
}
  
// Driver code
int main()
{
    struct Node* root = NULL;
    root = insert(root, 20);
    insert(root, 10);
    insert(root, 5);
    insert(root, 15);
    insert(root, 30);
    insert(root, 25);
    insert(root, 35);
    int a = 5, b = 55;
    cout << findDistWrapper(root, 5, 35);
    return 0;
}


Java
// Java program to find distance between 
// two nodes in BST 
class GfG { 
  
static class Node { 
    Node left, right; 
    int key; 
}
  
static Node newNode(int key) 
{ 
    Node ptr = new Node(); 
    ptr.key = key; 
    ptr.left = null;
    ptr.right = null; 
    return ptr; 
} 
  
// Standard BST insert function 
static Node insert(Node root, int key) 
{ 
    if (root == null) 
        root = newNode(key); 
    else if (root.key > key) 
        root.left = insert(root.left, key); 
    else if (root.key < key) 
        root.right = insert(root.right, key); 
    return root; 
} 
  
// This function returns distance of x from 
// root. This function assumes that x exists 
// in BST and BST is not NULL. 
static int distanceFromRoot(Node root, int x) 
{ 
    if (root.key == x) 
        return 0; 
    else if (root.key > x) 
        return 1 + distanceFromRoot(root.left, x); 
    return 1 + distanceFromRoot(root.right, x); 
} 
  
// Returns minimum distance beween a and b. 
// This function assumes that a and b exist 
// in BST. 
static int distanceBetween2(Node root, int a, int b) 
{ 
    if (root == null) 
        return 0; 
  
    // Both keys lie in left 
    if (root.key > a && root.key > b) 
        return distanceBetween2(root.left, a, b); 
  
    // Both keys lie in right 
    if (root.key < a && root.key < b) // same path 
        return distanceBetween2(root.right, a, b); 
  
    // Lie in opposite directions (Root is 
    // LCA of two nodes) 
    if (root.key >= a && root.key <= b) 
        return distanceFromRoot(root, a) + distanceFromRoot(root, b);
          
    return 0;
} 
  
// This function make sure that a is smaller 
// than b before making a call to findDistWrapper() 
static int findDistWrapper(Node root, int a, int b) 
{ 
    int temp = 0;
if (a > b) 
    {
    temp = a;
    a = b;
    b = temp;
    } 
return distanceBetween2(root, a, b); 
} 
  
// Driver code 
public static void main(String[] args) 
{ 
    Node root = null; 
    root = insert(root, 20); 
    insert(root, 10); 
    insert(root, 5); 
    insert(root, 15); 
    insert(root, 30); 
    insert(root, 25); 
    insert(root, 35); 
    System.out.println(findDistWrapper(root, 5, 35));
}
}


Python3
# Python3 program to find distance between 
# two nodes in BST 
class newNode: 
  
    # Constructor to create a new node 
    def __init__(self, data): 
        self.key = data 
        self.left = None
        self.right = None
  
# Standard BST insert function 
def insert(root, key):
    if root == None:
        root = newNode(key) 
    elif root.key > key: 
        root.left = insert(root.left, key) 
    elif root.key < key: 
        root.right = insert(root.right, key) 
    return root
  
# This function returns distance of x from 
# root. This function assumes that x exists 
# in BST and BST is not NULL. 
def distanceFromRoot(root, x):
    if root.key == x: 
        return 0
    elif root.key > x:
        return 1 + distanceFromRoot(root.left, x) 
    return 1 + distanceFromRoot(root.right, x)
  
# Returns minimum distance beween a and b. 
# This function assumes that a and b exist 
# in BST. 
def distanceBetween2(root, a, b):
    if root == None:
        return 0
  
    # Both keys lie in left 
    if root.key > a and root.key > b: 
        return distanceBetween2(root.left, a, b) 
  
    # Both keys lie in right 
    if root.key < a and root.key < b: # same path 
        return distanceBetween2(root.right, a, b)
  
    # Lie in opposite directions 
    # (Root is LCA of two nodes) 
    if root.key >= a and root.key <= b: 
        return (distanceFromRoot(root, a) + 
                distanceFromRoot(root, b))
  
# This function make sure that a is smaller 
# than b before making a call to findDistWrapper() 
def findDistWrapper(root, a, b):
    if a > b:
        a, b = b, a 
    return distanceBetween2(root, a, b)
  
# Driver code 
if __name__ == '__main__':
    root = None
    root = insert(root, 20) 
    insert(root, 10) 
    insert(root, 5) 
    insert(root, 15) 
    insert(root, 30) 
    insert(root, 25) 
    insert(root, 35)
    a, b = 5, 55
    print(findDistWrapper(root, 5, 35)) 
  
# This code is contributed by PranchalK


C#
// C# program to find distance between 
// two nodes in BST 
using System;
  
class GfG 
{ 
  
public class Node 
{ 
    public Node left, right; 
    public int key; 
} 
  
static Node newNode(int key) 
{ 
    Node ptr = new Node(); 
    ptr.key = key; 
    ptr.left = null; 
    ptr.right = null; 
    return ptr; 
} 
  
// Standard BST insert function 
static Node insert(Node root, int key) 
{ 
    if (root == null) 
        root = newNode(key); 
    else if (root.key > key) 
        root.left = insert(root.left, key); 
    else if (root.key < key) 
        root.right = insert(root.right, key); 
    return root; 
} 
  
// This function returns distance of x from 
// root. This function assumes that x exists 
// in BST and BST is not NULL. 
static int distanceFromRoot(Node root, int x) 
{ 
    if (root.key == x) 
        return 0; 
    else if (root.key > x) 
        return 1 + distanceFromRoot(root.left, x); 
    return 1 + distanceFromRoot(root.right, x); 
} 
  
// Returns minimum distance beween a and b. 
// This function assumes that a and b exist 
// in BST. 
static int distanceBetween2(Node root, int a, int b) 
{ 
    if (root == null) 
        return 0; 
  
    // Both keys lie in left 
    if (root.key > a && root.key > b) 
        return distanceBetween2(root.left, a, b); 
  
    // Both keys lie in right 
    if (root.key < a && root.key < b) // same path 
        return distanceBetween2(root.right, a, b); 
  
    // Lie in opposite directions (Root is 
    // LCA of two nodes) 
    if (root.key >= a && root.key <= b) 
        return distanceFromRoot(root, a) + 
                distanceFromRoot(root, b); 
          
    return 0; 
} 
  
// This function make sure that a is smaller 
// than b before making a call to findDistWrapper() 
static int findDistWrapper(Node root, int a, int b) 
{ 
    int temp = 0; 
if (a > b) 
    { 
    temp = a; 
    a = b; 
    b = temp; 
    } 
return distanceBetween2(root, a, b); 
} 
  
// Driver code 
public static void Main(String[] args) 
{ 
    Node root = null; 
    root = insert(root, 20); 
    insert(root, 10); 
    insert(root, 5); 
    insert(root, 15); 
    insert(root, 30); 
    insert(root, 25); 
    insert(root, 35); 
    Console.WriteLine(findDistWrapper(root, 5, 35)); 
} 
} 
  
// This code contributed by Rajput-Ji


输出:

4

时间复杂度: O(h),其中h是二进制搜索树的高度。