Binary Search Tree Analysis based on Wikipedia

Read more from wikipedia: http://en.wikipedia.org/wiki/Binary_search_tree 

1. what is it?  

 a node-based binary tree data structure which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • The left and right subtree must each also be a binary search tree.
  • There must be no duplicate nodes.

2. Time complexity: 

Time complexity
in big O notation
 AverageWorst case
SpaceO(n)O(n)
SearchO(log n)O(n)
InsertO(log n)O(n)
DeleteO(log n)O(n)

3. Operations: 

 1) search algorithm in pseudocode: 

  iterative version, finds a BST node:

algorithm Find(key, root):
    current-node := root
    while current-node is not Nil do
        if current-node.key = key then
            return current-node
        else if key < current-node.key then
            current-node := current-node.left
        else
            current-node := current-node.right

The following recursive version is equivalent:

algorithm Find-recursive(key, node):  // call initially with node = root
    if node = Nil or node.key = key then
        node
    else if key < node.key then
        Find-recursive(key, node.left)
    else
        Find-recursive(key, node.right)

 2) a typical BST insertion might be performed in C++:

void insert(int value)
{
    if(root == NULL)
        root = new Node(value);
    else
        insertHelper(root, value);
}
 
void insertHelper(Node* node, int value)
{
    if(value < node->key)
    {
        if(node->leftChild == NULL)
            node->leftChild = new Node(value);
        else
            insertHelper(node->leftChild, value);
    }
    else
    {
        if(node->rightChild == NULL)
            node->rightChild = new Node(value);
        else
            insertHelper(node->rightChild, value);
    }
}

an iterative approach to inserting into a binary search tree in Java:

private Node m_root;
 
public void insert(int data) {
    if (m_root == null) {
        m_root = new TreeNode(data, null, null);
        return;
    }
    Node root = m_root;
    while (root != null) {
        // Choose not add 'data' if already present (an implementation decision)
        if (data == root.getData()) {
            return;
        } else if (data < root.getData()) {
            // insert left
            if (root.getLeft() == null) {
                root.setLeft(new TreeNode(data, null, null));
                return;
            } else {
                root = root.getLeft();
            }
        } else {
            // insert right
            if (root.getRight() == null) {
                root.setRight(new TreeNode(data, null, null));
                return;
            } else {
                root = root.getRight();
            }
        }
    }
}

Below is a recursive approach to the insertion method.

private Node m_root;
 
public void insert(int data){
    if (m_root == null) {
        m_root = new TreeNode(data, null, null);        
    } else {
        internalInsert(m_root, data);
    }
}
 
private static void internalInsert(Node node, int data){
    // Choose not add 'data' if already present (an implementation decision)
    if (data == node.getKey()) {
        return;
    } else if (data < node.getKey()) {
        if (node.getLeft() == null) {
            node.setLeft(new TreeNode(data, null, null));
        } else {
            internalInsert(node.getLeft(), data);
        }
    } else {
        if (node.getRight() == null) {
            node.setRight(new TreeNode(data, null, null));
        } else {
            internalInsert(node.getRight(), data);
        }       
    }
}


3) Deletion: 3 types: 

  • Deleting a leaf (node with no children): Deleting a leaf is easy, as we can simply remove it from the tree.
  • Deleting a node with one child: Remove the node and replace it with its child.
  • Deleting a node with two children: Call the node to be deleted N. Do not delete N. Instead, choose either its in-order successor node or its in-order predecessor node, R. Replace the value of N with the value of R, then delete R.


 code in C Sharp:

private static Node Search(Node tree, double data, out Node parent)
{
    // empty tree
    if (tree == null)
    {
        parent = null;
        return null;
    }
 
    // node to find is the tree root
    if (data == tree.data)
    {
        parent = null;
        return tree;
    }
 
    // peek left
    if (tree.left != null && data == tree.left.data)
    {
        parent = tree;
        return tree.left;
    }
 
    // peek right
    if (tree.right != null && data == tree.right.data)
    {
        parent = tree;
        return tree.right;
    }
 
    if (data < tree.data)
        return Search(tree.left, data, out parent);
 
    if (data > tree.data)
        return Search(tree.right, data, out parent);
 
    // unreacheable code
    parent = null;
    return null;
}
 
public static Node Smallest(Node tree, out Node parent)
{
    if (tree == null)
    {
        parent = null;
        return null;
    }
 
    if (tree.left == null)
    {
        parent = null;
        return tree;
    }
 
    if (tree.left.left == null)
    {
        parent = tree;
        return tree.left;
    }
 
    return Smallest(tree.left, out parent);
}
 
public static void Remove(ref Node tree, double data)
{
    Node NodeToRemove, NodeToMove, parent;
    // Find node to remove
    NodeToRemove = Search(tree, data, out parent);
 
    // if the value is not found, return
    if (NodeToRemove == null) return;
 
    // Deleting a leaf or a node with one child: 
    // Remove the node and replace it with the child (or null if it has none)
    if (NodeToRemove.left == null || NodeToRemove.right == null)
    {
        // Get a reference to the child
        Node child;
        if (NodeToRemove.left == null)
            child = NodeToRemove.right;
        else
            child = NodeToRemove.left;
 
        // if the node is the root of the tree
        if (parent == null)
            tree = child;
 
        // if the node has a parent
        else
        {
            if (NodeToRemove.data > parent.data)
                parent.right = child;
            else
                parent.left = child;
        }
        return;
    }
    // Deleting a node with two children: 
    // Call the node to be deleted N. Do not delete N. 
    // Instead, choose either its in-order successor node or its in-order predecessor node, R. 
    // Replace the value of N with the value of R, then delete R.
    NodeToMove = Smallest(NodeToRemove.right, out parent);
 
    // replace the value
    NodeToRemove.data = NodeToMove.data;
 
    // Remove the bottom node
    Remove(ref NodeToMove, NodeToMove.data);
    if (parent == null)
        NodeToRemove.right = NodeToMove;
    else
        parent.left = NodeToMove;
}

code in C++.

template <typename T>
bool BST<T>::remove(const T & itemToDelete)
{
        return remove(root, itemToDelete);
}
 
template <typename T>
bool BST<T>::remove(Node<T>* & ptr, const T& key)       //helper remove function
{
        if (ptr==nullptr)
                return false;   // item not in BST
 
        if (key < ptr->data)
                remove(ptr->LeftChild, key);
        else if (key > ptr->data)
                remove(ptr->RightChild, key);
        else
        {
                Node<T> *temp;
 
                if (ptr->LeftChild==nullptr)
                {
                        temp = ptr->RightChild;
                        delete ptr;
                        ptr = temp;
                }
                else if (ptr->RightChild==nullptr)
                {
                        temp = ptr->LeftChild;
                        delete ptr;
                        ptr = temp;
                }
                else    //2 children
                {
                        temp = ptr->RightChild;
                        Node<T> *parent = nullptr;
 
                        while(temp->LeftChild!=nullptr)
                        {
                                parent = temp;
                                temp = temp->LeftChild;
                        }
                        ptr->data = temp->data;
                        if (parent != nullptr)
                                remove(parent->LeftChild, parent->LeftChild->data);
                        else
                                remove(ptr->RightChild, ptr->RightChild->data);
                }
        }
}

4) Traversal 

 An in-order traversal of a binary search tree will always result in a sorted list of node items (numbers, strings or other comparable items).

An in-order traversal algorithm for C is given below.

void in_order_traversal(struct Node *n, void (*cb)(void*))
{
        struct Node *cur, *pre;
 
        if(!n)
                return;
 
        cur = n;
 
        while(cur) {
                if(!cur->left) {
                        cb(cur->val);
                        cur= cur->right;
                } else {
                        pre = cur->left;
 
                        while(pre->right && pre->right != cur)
                                pre = pre->right;
 
                        if (!pre->right) {
                                pre->right = cur;
                                cur = cur->left;
                        } else {
                                pre->right = NULL;
                                cb(cur->val);
                                cur = cur->right;
                        }
                }
        }
}

5) Sort:  Similar to heapsort, we insert all the values we wish to sort into a new ordered data structure—in this case a binary search tree—and then traverse it in order, building our result.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值