"Algorithm" Note 8 - binary search tree

  • Binary search tree
    • Seek
    • insert
    • performance
  • Orderliness related operations
    • The biggest key, the minimum key
    • Rounding up, rounding down
    • Selection, ranking
    • Find a range
  • Deletion
    • Delete keys maximum, minimum key
    • General deletion

Binary search tree

Front understanding of disordered and ordered an array of linked lists at least in terms of performance linear level, can not be used for large data applications. Next to learn binary search tree can be inserted into the list of the flexibility and efficiency of an ordered array of looking to combine computer science is one of the most important algorithms.
A binary search tree (Binary Search Tree) is a binary tree in which each node contains a Comparable key, and the value associated with each node keys are larger than the left subtree of any node key, the key is smaller than the right subtree of any node.

Seek

When a binary search tree search, if the tree is empty, then search miss; if it is equal to find the keys and root keys, to find a hit, otherwise it recursively in sub-tree continued to find, if it is to find the key is less than the root, you select the left sub-tree, or choose the right subtree.
The code search algorithm implemented as:

public class BST<Key extends Comparable<Key>, Value> {
    private Node root;

    private class Node {
        private Key key;
        private Value val;
        private Node left, right;
        public int size;

        public Node(Key key, Value val, int size) {
            this.key = key;
            this.val = val;
            this.size = size;
        }
    }

    public Value get(Key key) {
        return get(root, key);
    }

    private Value get(Node x, Key key) {
        if (key == null)
            throw new IllegalArgumentException("calls get() with a null key");
        if (x == null)
            return null;
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
            return get(x.right, key);
        } else if (cmp < 0) {
            return get(x.left, key);
        } else {
            return x.val;
        }
    }
}

Wherein, the Node class is used to represent a binary search tree of nodes, each node contains keys, values, and a rear right and left link maximum minimum value can be used when the node counter of ordered operations.

insert

Upon insertion of the key, first to find, if the key already exists in the symbol table, updating the corresponding value; If the lookup miss, returns a new node containing the key-value pairs to be inserted.

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

private Node put(Node x, Key key, Value val) {
    if (key == null)
        throw new IllegalArgumentException("calls put() with a null key");
    if (x == null)
        return new Node(key, val, 1);
    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 {
        x.val = val;
    }
    x.size = size(x.left) + size(x.right) + 1;
    return x;
}

Insertion operation code find similar, but will insert nodes update or add a new node value, and updates the node counter.
x.left = put (x.left, key, val); code similar to the characteristics of simple recursive realized added settle point. When the recursive call, according to the equivalent binary logic to find, has a branch along the tree look down, if found, on the termination of recursion, the value of the update node, if the tree to the bottom did not find, at this time key == null establishment, recursion will terminate, and the new node initialization has been hanging in the x.left or x.right.
Release of the recursion procedure, equivalent to climb, climb each level along the tree, ; x.size = size (x.left) + size (x.right) +. 1 after will be executed, so that adding node All nodes on the size of the associated paths have been updated.

performance

And inserting new node will miss the need to search to find the bottom of the tree from the root node of the tree whole pieces, so the binary search tree shape-related properties of the tree, because the shape of the tree determines the depth of the tree. In the best case, a node contains N is perfectly balanced tree, all the links in the bottom space, as the distance from the root node LGN; and in the worst case, the tree becomes a shape become a list, the depth of the tree is N, selected in order by the element is inserted into the binary search tree, it can cause the problem. In the general case, the shape of the resulting tree closer to the best case, the performance of a binary search tree in the logarithmic level.
English original word "tale" greater than 7 in a total of 14,350 characters, these words have 5737 different words, these words as keys to test different properties of the symbol table to achieve the following results:

Abscissa represents the number of words inserted, the ordinate represents the number of comparisons at the time of insertion, the actual gray points represent a particular number of comparisons insertion, red dot represents the average number of comparisons (comparing Total / insert the number of words), studied based on the foregoing without order to achieve an orderly array of linked lists and the average number of 2246 and 484 times, respectively, can be seen in terms of a binary search tree compare the number of times the word or the average number of aspects, there is an order of magnitude leap forward.

Orderliness related operations

In addition to a binary search tree has a good performance, but also because of its orderliness and support to maintain key operations related to ordering.

The biggest key, the minimum key

Value of the left subtree of the node are smaller than a right subtree, the minimum value may be in the left subtree if the subtree is left empty, then the current node is the minimum. Based on this algorithm derived selecting the maximum value, the minimum value of the code is implemented:

public Key min() {
    if (isEmpty())
        throw new NoSuchElementException("calls min() with empty symbol table");
    return min(root).key;
}

private Node min(Node x) {
    if (x.left == null)
        return x;
    else
        return min(x.left);
}

public Key max() {
    if (isEmpty())
        throw new NoSuchElementException("calls max() with empty symbol table");
    return max(root).key;
}

private Node max(Node x) {
    if (x.right == null)
        return x;
    else
        return max(x.right);
}

Rounding up, rounding down

Key on the maximum rounding down, if the given key is less than the root key, then less than or equal to a root node in the left subtree, if the given key is greater than the root node, then only when the root the right subtree node is less than or equal to the present node given key, the rounded down value will appear in the right subtree, the root node is to find the value or rounded up method similar to this:
`` `
public Floor Key (Key Key) {
the Node = n-Floor (the root, Key);
IF (n-== null) {
return null;
} the else {
return n.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 n = floor(x.right, key);
if (n == null) {
    return x;
} else {
    return n;
}

}

public Key ceiling(Key key) {
if (n == null) {
return null;
} else {
return n.key;
}
}

private Node ceiling(Node x, Key key) {
if (x == null) {
return null;
}

int cmp = key.compareTo(x.key);
if (cmp == 0)
    return x;
if (cmp > 0)
    return ceiling(x.right, key);

Node n = ceiling(x.left, key);
if (n == null) {
    return x;
} else {
    return n;
}

}
```

Selection, ranking

Ranked from 0, SELECT selection method (k) returns the ranked key, a small tree to it there are k key. If the left subtree of nodes t is greater than k, it continues to look for in the left subtree, if t is equal to k, then the root is to find the key, if t is less than k, then look for ranking is in the right subtree kt-1 key, the code is thus obtained:

public Key select(int k) {
    return select(root, k).key;
}

private Node select(Node x, int k) {
    if (x == null) {
        return null;
    }

    int t = size(x.left);
    if (t > k) {
        return select(x.left, k);
    } else if (t < k) {
        return select(x.right, k - t - 1);
    } else {
        return x;
    }
}

Rank rank () method is the method of choice inverse method, which returns to the sort given key. If the given key is equal to the root node, the root key of the ranking is the total number of nodes in the left subtree t; if the given key is less than the root node, recursively calculated in the left subtree; if the given key is greater than the root node, returns t + 1 along with its position in the right subtree.

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 size(x.left) + rank(key, x.right) + 1;
    } else if (cmp < 0) {
        return rank(key, x.left);
    } else {
        return size(x.left);
    }
}

Find a range

Find all asked to return to the range of keys in a given range, this basic method will be used in the binary tree traversal - preorder. First traversal of all keys in the left subtree, then traverse the root node, and finally all the keys in the right subtree, this process recursively, it can be in ascending order of finish traverse all nodes.

public void keys(Node x, Queue<Key> queue, Key lo, Key hi) {
    if (x == null)
        return;
    int cmplo = lo.compareTo(x.key);
    int cmphi = hi.compareTo(x.key);
    if (cmplo < 0)
        keys(x.left, queue, lo, hi);
    if (cmplo <= 0 && cmphi >= 0)
        queue.enqueue(x.key);
    if (cmphi > 0)
        keys(x.right, queue, lo, hi);
}

Deletion

Delete keys maximum, minimum key

When you delete a minimum keys, you need to keep in-depth root of the left subtree, until she met an empty link, then the link to the node point to the right subtree of the node, the node to be deleted because not any object references, then the garbage collector will be cleared away. Delete the greatest key process is similar.

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

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

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

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

In the deepening of the left subtree of time, unless met air links, deleteMin (Node x) method returns the node x, only the last one before the last recursive node point x.right, recursive exit, will be updated on the path node counter.

General deletion

Binary search tree method is the most difficult to achieve the delete () method, and delete the maximum, minimum key, two child nodes are deleted node, only one is not empty, but generally there will be two nodes child nodes, delete this node, we need a reasonable deal with its two child nodes. T.Hibbard in 1962 first proposed a method to solve this problem with its successor nodes to fill its position after deleting node x. Since x has a right child node, whereby its successor node point which is the most Summary of the right subtree. Such alterations can still guarantee the orderliness of the tree, because there is no other bond between x.key and its successor node. Complete this operation requires four steps:

  • Save point node is about to be deleted links to t;
  • The point x its successor node min (t.right);
  • The right link of x (originally a point to all the nodes are larger than x.key binary search tree) point deleteMin (t.right), that is, after deleting all the nodes are still over the latter's son and two forks x.key Find a tree.
  • The left link of x (originally empty) set t.left (under which all keys are smaller than the deleted node and its successor node).
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.size = size(x.left) + size(x.right) + 1;
    return x;
}

Guess you like

Origin www.cnblogs.com/zhixin9001/p/11621670.html