原文地址:Binary Search Tree | Set 1 (Search and Insertion)
下面是二叉查找树(BST)的定义:
二叉查找树是一种基于二叉树的数据结构,它又下列属性:
- 一个节点的key大于它左子树包含所有节点的key;
- 一个节点的key小于它右子树包含所有节点的key;
- 左右子树必须都是二叉查找树;
树中不能有重复的节点。
二叉查找树的上述属性使得它们的key是有序的,所以像查询,最小值,最大值等操作可以很快地完成。如果没有顺序的话,那么我们要查询key的话要比较每一个key了。
查询key
在二叉查找树中搜索一个已知的key,我们首先是要与根节点进行比较的,如果这个key表示的就是根节点,那么就返回根节点。如果key比根节点的key要大,那么我们递归到它的右子树的根节点。否则递归左子树的根节点。
// 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;
// val is greater than root's key
if (root.key > key)
return search(root.left, key);
// val is less than root's key
return search(root.right, key);
}
描述:
插入key
一个新的key总是被插到叶子节点处。我们从根节点开始查询一个key一直到一个叶子节点。一旦找到一个叶子节点,那么这新的节点就加进去作为这个叶子节点的一个孩子。
100 100
/ \ Insert 40 / \
20 500 ---------> 20 500
/ \ / \
10 30 10 30
\
40
// 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 Program to test above functions
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
输出:
20
30
40
50
60
70
80
时间复杂度:搜索和插入在最差情况下的时间复杂度是O(h),这里的h是二叉查找树的树高。在最差情况下,我们必须遍历根节点到最深的叶子节点。一个退化的树高可能变成n,然后搜索和插入操作的时间复杂度也就成了O(n)。
一些有趣的情况:
- 中序遍历二叉排序树输出是有序的;
- 我们可以只用先序遍历,后序遍历或者水平遍历就能构建一个二叉查找树。注意我们总是可以用排序一个已知的遍历得到中序遍历;
- n个不同key的BST数目是Catalan数Cn = (2n)!/(n+1)!*n!