您的位置:首页 > 其它

Binary Search Tree Analysis based on Wikipedia

2013-05-31 04:21 351 查看
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: