Binary Search Trees

1.  Binary Search Tree:

    a)  Definition : A BST is a binary tree in symmetric order.

         A binary tree is either:

         -- Empty.

         -- Two disjoint binary trees (left and right).

    b)  Symmetric order: Each node has a key, and every node’s key is:

         -- Larger than all keys in its left subtree.

         -- Smaller than all keys in its right subtree.

 

2.  Java definition: A BST is a reference to a root Node.

 

private class Node
{
    private Key key;
    private Value val;
    private Node left, right;
    public Node(Key key, Value val)
    {
        this.key = key;
        this.val = val;
    }
}

 

 

3.  Search:

    a) If less, go left; if greater, go right; if equal, search hit.

    b) Cost : Number of compares is equal to 1 + depth of node.

    c) Java Implementation :

 

public Value get(Key key)
{
    Node x = root;
    while (x != null)
    {
        int cmp = key.compareTo(x.key);
        if (cmp < 0) x = x.left;
        else if (cmp > 0) x = x.right;
        else if (cmp == 0) return x.val;
    }
    return null;
}

 

 

4.  Put:

    a)  If less, go left; if greater, go right; if equal, update value; if null, insert

    b)  Cost : Number of compares is equal to 1 + depth of node.

    c)  Java Implementation :

 

public void put(Key key, Value val)
{ 
    root = put(root, key, val); 
}

private Node put(Node x, Key key, Value val)
{
    if (x == null) return new Node(key, val);
    int cmp = key.compareTo(x.key);
    if (cmp < 0)
        x.left = put(x.left, key, val);
    else if (cmp > 0)
        x.right = put(x.right, key, val);
    else if (cmp == 0)
        x.val = val;
    return x;
}

 

 

5.  Tree shape :

    a)  Many BSTs correspond to same set of keys.

    b)  Tree shape depends on order of insertion.

 

6.  Correspondence between BSTs and quicksort partitioning : Correspondence is 1-1 if array has no duplicate keys.

 

7.  Mathematical Analysis : 

    a)  If N distinct keys are inserted into a BST in random order, the expected number of compares for a search/insert is ~ 2 ln N. (1-1 correspondence with quicksort partitioning.)

    b)  If N distinct keys are inserted in random order, expected height of tree ( the longest path) is ~ 4.311 ln N.

    c)  Worst-case height is N when keys are inserted in ascending order.

 

8.  Ordered Operations:

    a)  Minimum : most left key

    b)  Maximum : most right key

    c)  Floor : Largest key ≤ a given key k:

        1)  k equals the key at root -- The floor of k is k.

        2)  k is less than the key at root -- The floor of k is in the left subtree.

        3)  k is greater than the key at root -- The floor of k is in the right subtree (if there is any key ≤ k in right subtree); otherwise it is the key in the root.

        4)  Java Implementation :

        

public Key floor(Key key)
{
    Node x = floor(root, key);
    if (x == null) return null;
    return x.key;
}

private Node floor(Node x, Key key)
{
    if (x == null) return null;
    int cmp = key.compareTo(x.key);
    if (cmp == 0) return x;
    if (cmp < 0) return floor(x.left, key);
    Node t = floor(x.right, key);
    if (t != null) return t;
    else return x;
}

    d)  Ceiling : Smallest key ≥ a given key k. ( similar to Floor )

 

    e)  Size of Subtree :  In each node, we store the number of nodes in the subtree rooted at that

node:

 

private class Node
{
    private Key key;
    private Value val;
    private Node left;
    private Node right;
    private int count;
}

public int size()
{ 
    return size(root); 
}

private int size(Node x)
{
    if (x == null) return 0;
    return x.count;
}

private Node put(Node x, Key key, Value val)
{
    if (x == null) return new Node(key, val);
    int cmp = key.compareTo(x.key);
    if (cmp < 0) x.left = put(x.left, key, val);
    else if (cmp > 0) x.right = put(x.right, key, val);
    else if (cmp == 0) x.val = val;
    x.count = 1 + size(x.left) + size(x.right);
    return x;
}

     f)  Rank. How many keys < k

 

 

public int rank(Key key)
{ 
    return rank(key, root); 
}

private int rank(Key key, Node x)
{
    if (x == null) return 0;
    int cmp = key.compareTo(x.key);
    if (cmp < 0) return rank(key, x.left);
    else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right);
    else if (cmp == 0) return size(x.left);
}

 

 

9.  Inorder Tranversal

    a)  traverse left subtree; enqueue key; traverse right subtree.

    b)  Inorder traversal of a BST yields keys in ascending order.

    c)  Java Implementation : 

 

public Iterable<Key> keys()
{
    Queue<Key> q = new Queue<Key>();
    inorder(root, q);
    return q;
}

private void inorder(Node x, Queue<Key> q)
{
    if (x == null) return;
    inorder(x.left, q);
    q.enqueue(x.key);
    inorder(x.right, q);
}

 

 

10. Deletion:

    a)  lazy approach : 

        1)  Set the value of node to be deleted to null.

        2)  Leave key in tree to guide searches (but don't consider it equal in search).

        3)  Cost : ~ 2 ln N' per insert, search, and delete (if keys in random order), where N' is the number of key-value pairs ever inserted in the BST.

        4)  Unsatisfactory solution: Tombstone (memory) overload.

    b)  Deleting Minimum:

        1)  Go left until finding a node with a null left link.

        2)  Replace that node by its right link.

        3)  Update subtree counts.

        4)  Java Implementation :

 

public void deleteMin()
{ 
    root = deleteMin(root); 
}

private Node deleteMin(Node x)
{
    if (x.left == null) return x.right;
    x.left = deleteMin(x.left);
    x.count = 1 + size(x.left) + size(x.right);
    return x;
}

     c)  Hibbard Deletion :

        1) [0 children] Delete t by setting parent link to null.

        2) [1 child] Delete t by replacing parent link.

        3) [2 children] Find successor x of t. Delete the minimum x in t's right subtree.Put x in t's spot.

        4) Java Implementation:

public void delete(Key key)
{ 
    root = delete(root, key); 
}

private Node delete(Node x, Key key) {
    if (x == null) return null;
    int cmp = key.compareTo(x.key);
    if (cmp < 0) x.left = delete(x.left, key);
    else if (cmp > 0) x.right = delete(x.right, key);
    else {
        if (x.right == null) return x.left;
        if (x.left == null) return x.right;
        Node t = x;
        x = min(t.right);
        x.right = deleteMin(t.right);
        x.left = t.left;
    }
    x.count = size(x.left) + size(x.right) + 1;
    return x;
}

        5) Unsatisfactory solution: Not symmetric. Trees not random (!) ⇒ sqrt (N) per op.

你可能感兴趣的:(BST)