📜  二进制搜索树|设置1(搜索和插入)

📅  最后修改于: 2021-05-24 22:10:49             🧑  作者: Mango

以下是根据Wikipedia的Binary Search Tree(BST)的定义
二进制搜索树是基于节点的二进制树数据结构,具有以下属性:

  • 节点的左子树仅包含键值小于节点键值的节点。
  • 节点的右子树仅包含键大于该节点的键的节点。
  • 左和右子树也都必须是二叉搜索树。
    不得有重复的节点。

200px-Binary_search_tree.svg

二进制搜索树的上述属性提供了键之间的顺序,以便可以快速完成搜索,最小和最大等操作。如果没有排序,那么我们可能必须比较每个键以搜索给定的键。

搜索钥匙
为了搜索值,如果我们有一个排序数组,我们可以执行二进制搜索。假设我们要在数组中搜索数字,就像在二进制搜索中所做的那样,就是我们首先将完整列表定义为我们的搜索空间,该数字只能存在于搜索空间内。现在,我们将要搜索的数字或要搜索的元素与搜索空间的中间元素或中位数进行比较,如果要搜索的记录较少,则在左半部分搜索,否则在右半部分搜索,在相等的情况下,我们找到了元素。在二进制搜索中,我们从搜索空间中的“ n”个元素开始,然后如果中间元素不是我们要寻找的元素,我们将搜索空间减小为“ n / 2”,然后继续减小搜索空间,直到要么找到我们正在寻找的记录,要么只找到搜索空间中的一个元素,然后完成整个归约。
二叉搜索树中的搜索操作将非常相似。假设我们要搜索数字,我们要做的是从根开始,然后将要搜索的值与根的值进行比较(如果相等),那么如果知道我们需要转到左子树的情况越少,因为在二叉搜索树中,左子树中的所有元素都较小,而右子树中的所有元素都较大。在二叉搜索树中搜索元素基本上就是这种遍历,在该遍历中,每一步我们都将向左或向右移动,因此在每一步中,我们将丢弃其中一个子树。如果树是平衡的,则对于所有节点,如果左右子树的高度之差不大于1,则我们将其称为树平衡,我们将从“ n”个节点的搜索空间开始,并且当我们丢弃其中一个在子树中,我们将丢弃“ n / 2”个节点,因此我们的搜索空间将减小为“ n / 2” ,然后在下一步中,我们将搜索空间减小为“ n / 4”,然后继续减小直到找到元素或将搜索空间缩小到只有一个节点为止。这里的搜索也是二进制搜索,这就是为什么命名二进制搜索树的原因。

C++
// C function to search a given key in a given BST
struct node* search(struct node* root, int key)
{
    // Base Cases: root is null or key is present at root
    if (root == NULL || root->key == key)
       return root;
    
    // Key is greater than root's key
    if (root->key < key)
       return search(root->right, key);
 
    // Key is smaller than root's key
    return search(root->left, key);
}


Java
// A utility function to search a given key in BST
public Node search(Node root, int key)
{
    // Base Cases: root is null or key is present at root
    if (root==null || root.key==key)
        return root;
 
    // Key is greater than root's key
    if (root.key < key)
       return search(root.right, key);
 
    // Key is smaller than root's key
    return search(root.left, key);
}


Python
# A utility function to search a given key in BST
def search(root,key):
     
    # Base Cases: root is null or key is present at root
    if root is None or root.val == key:
        return root
 
    # Key is greater than root's key
    if root.val < key:
        return search(root.right,key)
   
    # Key is smaller than root's key
    return search(root.left,key)
 
# This code is contributed by Bhavya Jain


C#
// A utility function to search
// a given key in BST
public Node search(Node root,
                   int key)
{
    // Base Cases: root is null
    // or key is present at root
    if (root == null ||
        root.key == key)
        return root;
 
   // Key is greater than root's key
    if (root.key < key)
       return search(root.right, key);
 
    // Key is smaller than root's key
    return search(root.left, key);
}
 
// This code is contributed by gauravrajput1


C++
// C++ program to demonstrate insertion
// in a BST recursively.
#include 
using namespace std;
 
class BST
{
    int data;
    BST *left, *right;
 
public:
    // Default constructor.
    BST();
 
    // Parameterized constructor.
    BST(int);
 
    // Insert function.
    BST* Insert(BST*, int);
 
    // Inorder traversal.
    void Inorder(BST*);
};
 
// Default Constructor definition.
BST ::BST()
    : data(0)
    , left(NULL)
    , right(NULL)
{
}
 
// Parameterized Constructor definition.
BST ::BST(int value)
{
    data = value;
    left = right = NULL;
}
 
// Insert function definition.
BST* BST ::Insert(BST* root, int value)
{
    if (!root)
    {
        // Insert the first node, if root is NULL.
        return new BST(value);
    }
 
    // Insert data.
    if (value > root->data)
    {
        // Insert right node data, if the 'value'
        // to be inserted is greater than 'root' node data.
 
        // Process right nodes.
        root->right = Insert(root->right, value);
    }
    else
    {
        // Insert left node data, if the 'value'
        // to be inserted is greater than 'root' node data.
 
        // Process left nodes.
        root->left = Insert(root->left, value);
    }
 
    // Return 'root' node, after insertion.
    return root;
}
 
// Inorder traversal function.
// This gives data in sorted order.
void BST ::Inorder(BST* root)
{
    if (!root) {
        return;
    }
    Inorder(root->left);
    cout << root->data << endl;
    Inorder(root->right);
}
 
// Driver code
int main()
{
    BST b, *root = NULL;
    root = b.Insert(root, 50);
    b.Insert(root, 30);
    b.Insert(root, 20);
    b.Insert(root, 40);
    b.Insert(root, 70);
    b.Insert(root, 60);
    b.Insert(root, 80);
 
    b.Inorder(root);
    return 0;
}
 
// This code is contributed by pkthapa


C
// C program to demonstrate insert
// operation in binary
// search tree.
#include 
#include 
 
struct node {
    int key;
    struct node *left, *right;
};
 
// A utility function to create a new BST node
struct node* newNode(int item)
{
    struct node* temp
        = (struct node*)malloc(sizeof(struct node));
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
 
// A utility function to do inorder traversal of BST
void inorder(struct node* root)
{
    if (root != NULL) {
        inorder(root->left);
        printf("%d \n", root->key);
        inorder(root->right);
    }
}
 
/* A utility function to insert
   a new node with given key in
 * BST */
struct node* insert(struct node* node, int key)
{
    /* If the tree is empty, return a new node */
    if (node == NULL)
        return newNode(key);
 
    /* Otherwise, recur down the tree */
    if (key < node->key)
        node->left = insert(node->left, key);
    else if (key > node->key)
        node->right = insert(node->right, key);
 
    /* return the (unchanged) node pointer */
    return node;
}
 
// Driver Code
int main()
{
    /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
    struct node* root = NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
 
    // print inoder traversal of the BST
    inorder(root);
 
    return 0;
}


Java
// Java program to demonstrate
// insert operation in binary
// search tree
class BinarySearchTree {
 
    /* Class containing left
       and right child of current node
     * and key value*/
    class Node
    {
        int key;
        Node left, right;
 
        public Node(int item)
        {
            key = item;
            left = right = null;
        }
    }
 
    // Root of BST
    Node root;
 
    // Constructor
    BinarySearchTree()
    {
         root = null;
    }
 
    // This method mainly calls insertRec()
    void insert(int key)
    {
         root = insertRec(root, key);
    }
 
    /* A recursive function to
       insert a new key in BST */
    Node insertRec(Node root, int key)
    {
 
        /* If the tree is empty,
           return a new node */
        if (root == null)
        {
            root = new Node(key);
            return root;
        }
 
        /* Otherwise, recur down the tree */
        if (key < root.key)
            root.left = insertRec(root.left, key);
        else if (key > root.key)
            root.right = insertRec(root.right, key);
 
        /* return the (unchanged) node pointer */
        return root;
    }
 
    // This method mainly calls InorderRec()
    void inorder()
    {
         inorderRec(root);
    }
 
    // A utility function to
    // do inorder traversal of BST
    void inorderRec(Node root)
    {
        if (root != null) {
            inorderRec(root.left);
            System.out.println(root.key);
            inorderRec(root.right);
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        BinarySearchTree tree = new BinarySearchTree();
 
        /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
        tree.insert(50);
        tree.insert(30);
        tree.insert(20);
        tree.insert(40);
        tree.insert(70);
        tree.insert(60);
        tree.insert(80);
 
        // print inorder traversal of the BST
        tree.inorder();
    }
}
// This code is contributed by Ankur Narain Verma


Python
# Python program to demonstrate
# insert operation in binary search tree
 
# A utility class that represents
# an individual node in a BST
 
 
class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.val = key
 
# A utility function to insert
# a new node with the given key
 
 
def insert(root, key):
    if root is None:
        return Node(key)
    else:
        if root.val == key:
            return root
        elif root.val < key:
            root.right = insert(root.right, key)
        else:
            root.left = insert(root.left, key)
    return root
 
# A utility function to do inorder tree traversal
 
 
def inorder(root):
    if root:
        inorder(root.left)
        print(root.val)
        inorder(root.right)
 
 
# Driver program to test the above functions
# Let us create the following BST
#    50
#  /     \
# 30     70
#  / \ / \
# 20 40 60 80
 
r = Node(50)
r = insert(r, 30)
r = insert(r, 20)
r = insert(r, 40)
r = insert(r, 70)
r = insert(r, 60)
r = insert(r, 80)
 
# Print inoder traversal of the BST
inorder(r)


C#
// C# program to demonstrate
// insert operation in binary
// search tree
using System;
 
class BinarySearchTree{
     
// Class containing left and
// right child of current node
// and key value
public class Node
{
    public int key;
    public Node left, right;
 
    public Node(int item)
    {
        key = item;
        left = right = null;
    }
}
 
// Root of BST
Node root;
 
// Constructor
BinarySearchTree()
{
    root = null;
}
 
// This method mainly calls insertRec()
void insert(int key)
{
    root = insertRec(root, key);
}
 
// A recursive function to insert
// a new key in BST
Node insertRec(Node root, int key)
{
     
    // If the tree is empty,
    // return a new node
    if (root == null)
    {
        root = new Node(key);
        return root;
    }
 
    // Otherwise, recur down the tree
    if (key < root.key)
        root.left = insertRec(root.left, key);
    else if (key > root.key)
        root.right = insertRec(root.right, key);
 
    // Return the (unchanged) node pointer
    return root;
}
 
// This method mainly calls InorderRec()
void inorder()
{
    inorderRec(root);
}
 
// A utility function to
// do inorder traversal of BST
void inorderRec(Node root)
{
    if (root != null)
    {
        inorderRec(root.left);
        Console.WriteLine(root.key);
        inorderRec(root.right);
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    BinarySearchTree tree = new BinarySearchTree();
 
    /* Let us create following BST
          50
       /     \
      30      70
     /  \    /  \
   20   40  60   80 */
    tree.insert(50);
    tree.insert(30);
    tree.insert(20);
    tree.insert(40);
    tree.insert(70);
    tree.insert(60);
    tree.insert(80);
     
    // Print inorder traversal of the BST
    tree.inorder();
}
}
 
// This code is contributed by aashish1995


在下面的树中搜索6的插图:
1.从根开始。
2.将搜索元素与根进行比较,如果小于根,则向左递归,向右递归。
3.如果在任何位置都找到要搜索的元素,则返回true,否则返回false。

搜索

插入钥匙
新密钥始终插入在叶子上。我们从根开始搜索一个键,直到找到叶节点。找到叶节点后,将新节点添加为叶节点的子节点。

100                               100
        /   \        Insert 40            /    \
      20     500    --------->          20     500 
     /  \                              /  \  
    10   30                           10   30
                                              \   
                                              40

C++

// C++ program to demonstrate insertion
// in a BST recursively.
#include 
using namespace std;
 
class BST
{
    int data;
    BST *left, *right;
 
public:
    // Default constructor.
    BST();
 
    // Parameterized constructor.
    BST(int);
 
    // Insert function.
    BST* Insert(BST*, int);
 
    // Inorder traversal.
    void Inorder(BST*);
};
 
// Default Constructor definition.
BST ::BST()
    : data(0)
    , left(NULL)
    , right(NULL)
{
}
 
// Parameterized Constructor definition.
BST ::BST(int value)
{
    data = value;
    left = right = NULL;
}
 
// Insert function definition.
BST* BST ::Insert(BST* root, int value)
{
    if (!root)
    {
        // Insert the first node, if root is NULL.
        return new BST(value);
    }
 
    // Insert data.
    if (value > root->data)
    {
        // Insert right node data, if the 'value'
        // to be inserted is greater than 'root' node data.
 
        // Process right nodes.
        root->right = Insert(root->right, value);
    }
    else
    {
        // Insert left node data, if the 'value'
        // to be inserted is greater than 'root' node data.
 
        // Process left nodes.
        root->left = Insert(root->left, value);
    }
 
    // Return 'root' node, after insertion.
    return root;
}
 
// Inorder traversal function.
// This gives data in sorted order.
void BST ::Inorder(BST* root)
{
    if (!root) {
        return;
    }
    Inorder(root->left);
    cout << root->data << endl;
    Inorder(root->right);
}
 
// Driver code
int main()
{
    BST b, *root = NULL;
    root = b.Insert(root, 50);
    b.Insert(root, 30);
    b.Insert(root, 20);
    b.Insert(root, 40);
    b.Insert(root, 70);
    b.Insert(root, 60);
    b.Insert(root, 80);
 
    b.Inorder(root);
    return 0;
}
 
// This code is contributed by pkthapa

C

// C program to demonstrate insert
// operation in binary
// search tree.
#include 
#include 
 
struct node {
    int key;
    struct node *left, *right;
};
 
// A utility function to create a new BST node
struct node* newNode(int item)
{
    struct node* temp
        = (struct node*)malloc(sizeof(struct node));
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
 
// A utility function to do inorder traversal of BST
void inorder(struct node* root)
{
    if (root != NULL) {
        inorder(root->left);
        printf("%d \n", root->key);
        inorder(root->right);
    }
}
 
/* A utility function to insert
   a new node with given key in
 * BST */
struct node* insert(struct node* node, int key)
{
    /* If the tree is empty, return a new node */
    if (node == NULL)
        return newNode(key);
 
    /* Otherwise, recur down the tree */
    if (key < node->key)
        node->left = insert(node->left, key);
    else if (key > node->key)
        node->right = insert(node->right, key);
 
    /* return the (unchanged) node pointer */
    return node;
}
 
// Driver Code
int main()
{
    /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
    struct node* root = NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
 
    // print inoder traversal of the BST
    inorder(root);
 
    return 0;
}

Java

// Java program to demonstrate
// insert operation in binary
// search tree
class BinarySearchTree {
 
    /* Class containing left
       and right child of current node
     * and key value*/
    class Node
    {
        int key;
        Node left, right;
 
        public Node(int item)
        {
            key = item;
            left = right = null;
        }
    }
 
    // Root of BST
    Node root;
 
    // Constructor
    BinarySearchTree()
    {
         root = null;
    }
 
    // This method mainly calls insertRec()
    void insert(int key)
    {
         root = insertRec(root, key);
    }
 
    /* A recursive function to
       insert a new key in BST */
    Node insertRec(Node root, int key)
    {
 
        /* If the tree is empty,
           return a new node */
        if (root == null)
        {
            root = new Node(key);
            return root;
        }
 
        /* Otherwise, recur down the tree */
        if (key < root.key)
            root.left = insertRec(root.left, key);
        else if (key > root.key)
            root.right = insertRec(root.right, key);
 
        /* return the (unchanged) node pointer */
        return root;
    }
 
    // This method mainly calls InorderRec()
    void inorder()
    {
         inorderRec(root);
    }
 
    // A utility function to
    // do inorder traversal of BST
    void inorderRec(Node root)
    {
        if (root != null) {
            inorderRec(root.left);
            System.out.println(root.key);
            inorderRec(root.right);
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        BinarySearchTree tree = new BinarySearchTree();
 
        /* Let us create following BST
              50
           /     \
          30      70
         /  \    /  \
       20   40  60   80 */
        tree.insert(50);
        tree.insert(30);
        tree.insert(20);
        tree.insert(40);
        tree.insert(70);
        tree.insert(60);
        tree.insert(80);
 
        // print inorder traversal of the BST
        tree.inorder();
    }
}
// This code is contributed by Ankur Narain Verma

Python

# Python program to demonstrate
# insert operation in binary search tree
 
# A utility class that represents
# an individual node in a BST
 
 
class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.val = key
 
# A utility function to insert
# a new node with the given key
 
 
def insert(root, key):
    if root is None:
        return Node(key)
    else:
        if root.val == key:
            return root
        elif root.val < key:
            root.right = insert(root.right, key)
        else:
            root.left = insert(root.left, key)
    return root
 
# A utility function to do inorder tree traversal
 
 
def inorder(root):
    if root:
        inorder(root.left)
        print(root.val)
        inorder(root.right)
 
 
# Driver program to test the above functions
# Let us create the following BST
#    50
#  /     \
# 30     70
#  / \ / \
# 20 40 60 80
 
r = Node(50)
r = insert(r, 30)
r = insert(r, 20)
r = insert(r, 40)
r = insert(r, 70)
r = insert(r, 60)
r = insert(r, 80)
 
# Print inoder traversal of the BST
inorder(r)

C#

// C# program to demonstrate
// insert operation in binary
// search tree
using System;
 
class BinarySearchTree{
     
// Class containing left and
// right child of current node
// and key value
public class Node
{
    public int key;
    public Node left, right;
 
    public Node(int item)
    {
        key = item;
        left = right = null;
    }
}
 
// Root of BST
Node root;
 
// Constructor
BinarySearchTree()
{
    root = null;
}
 
// This method mainly calls insertRec()
void insert(int key)
{
    root = insertRec(root, key);
}
 
// A recursive function to insert
// a new key in BST
Node insertRec(Node root, int key)
{
     
    // If the tree is empty,
    // return a new node
    if (root == null)
    {
        root = new Node(key);
        return root;
    }
 
    // Otherwise, recur down the tree
    if (key < root.key)
        root.left = insertRec(root.left, key);
    else if (key > root.key)
        root.right = insertRec(root.right, key);
 
    // Return the (unchanged) node pointer
    return root;
}
 
// This method mainly calls InorderRec()
void inorder()
{
    inorderRec(root);
}
 
// A utility function to
// do inorder traversal of BST
void inorderRec(Node root)
{
    if (root != null)
    {
        inorderRec(root.left);
        Console.WriteLine(root.key);
        inorderRec(root.right);
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    BinarySearchTree tree = new BinarySearchTree();
 
    /* Let us create following BST
          50
       /     \
      30      70
     /  \    /  \
   20   40  60   80 */
    tree.insert(50);
    tree.insert(30);
    tree.insert(20);
    tree.insert(40);
    tree.insert(70);
    tree.insert(60);
    tree.insert(80);
     
    // Print inorder traversal of the BST
    tree.inorder();
}
}
 
// This code is contributed by aashish1995
输出
20 
30 
40 
50 
60 
70 
80

在树下插入2的插图:
1.从根开始。
2.将插入元素与根进行比较,如果小于根,则向左递归,向右递归。
3.到达末端后,只需将该节点插入左侧(如果小于当前节点),然后插入右侧。

搜索

时间复杂度:搜索和插入操作的最坏情况下的时间复杂度为O(h),其中h是二进制搜索树的高度。在最坏的情况下,我们可能必须从根移动到最深的叶节点。倾斜树的高度可能变为n,搜索和插入操作的时间复杂度可能变为O(n)。

一些有趣的事实:

  • BST的顺序遍历始终会产生排序的输出。
  • 我们可以仅通过预订购或后订购或水平订单遍历来构造BST。请注意,我们始终可以通过对唯一给定的遍历进行排序来获得有序遍历。
  • 具有n个不同键的唯一BST的数量为加泰罗尼亚语编号

相关链接:

  • 二进制搜索树删除操作
  • 二进制搜索树上的测验
  • BST的编码实践
  • 关于BST的所有文章