以下是根据Wikipedia的Binary Search Tree(BST)的定义
二进制搜索树是基于节点的二进制树数据结构,具有以下属性:
- 节点的左子树仅包含键值小于节点键值的节点。
- 节点的右子树仅包含键大于该节点的键的节点。
- 左和右子树也都必须是二叉搜索树。
不得有重复的节点。
二进制搜索树的上述属性提供了键之间的顺序,以便可以快速完成搜索,最小和最大等操作。如果没有排序,那么我们可能必须比较每个键以搜索给定的键。
搜索钥匙
为了搜索值,如果我们有一个排序数组,我们可以执行二进制搜索。假设我们要在数组中搜索数字,就像在二进制搜索中所做的那样,就是我们首先将完整列表定义为我们的搜索空间,该数字只能存在于搜索空间内。现在,我们将要搜索的数字或要搜索的元素与搜索空间的中间元素或中位数进行比较,如果要搜索的记录较少,则在左半部分搜索,否则在右半部分搜索,在相等的情况下,我们找到了元素。在二进制搜索中,我们从搜索空间中的“ 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的所有文章