Binary Search Tree
-
#include <cstdio>
-
#include <iostream>
-
-
template <class Type>
-
struct bNode {
-
Type key;
-
bNode *link[2];
-
bNode(){
-
link[0] = NULL;
-
link[1] = NULL;
-
}
-
};
-
-
template <class Type>
-
class BinarySearchTree {
-
private:
-
int count;
-
bNode<Type> *root;
-
void clear(bNode<Type> *&ptr);
-
bool search(const Type &item, bNode<Type> *&curr, bNode<Type> *&prev, bool
-
&lr) const;
-
inline Type inOrder(bNode<Type> *ptr) const;
-
inline int subNodes(bNode<Type> * const &ptr) const;
-
int height(bNode<Type>* const &ptr) const;
-
bNode<Type>* minmax(bNode<Type> *ptr, const bool &lr) const;
-
public:
-
BinarySearchTree();
-
~BinarySearchTree();
-
void clear();
-
bool isEmpty() const;
-
bool insert(const Type &item);
-
bool remove(const Type &item);
-
bool search(const Type &item, Type *&ptr) const;
-
Type min() const;
-
Type max() const;
-
int size() const;
-
int height() const;
-
};
-
-
template <class Type>
-
void BinarySearchTree<Type>::clear(bNode<Type> *&ptr)
-
{
-
if (ptr != NULL) {
-
clear(ptr->link[0]); // clear left
-
clear(ptr->link[1]); // clear right;
-
delete ptr; // delete recursively
-
}
-
}
-
-
template <class Type>
-
bool BinarySearchTree<Type>::search(const Type &item, bNode<Type> *&curr,
-
bNode<Type> *&prev, bool &lr) const
-
{
-
while(curr != NULL) {
-
if (curr->key == item)
-
return true;
-
lr = (item > curr->key); // check bigger? go left : go right.
-
prev = curr;
-
curr = curr->link[lr];
-
}
-
return false;
-
}
-
-
template <class Type>
-
inline Type BinarySearchTree<Type>::inOrder(bNode<Type> *ptr) const
-
{
-
bool lr = 1;
-
Type temp;
-
bNode<Type> *prev = ptr;
-
-
ptr = ptr->link[1]; // right child.
-
// find a node which have no left child in the right subTree.
-
// find (neighbor) next item. which of course, have no left child.
-
while (ptr->link[0] != NULL) {
-
prev = ptr;
-
ptr = ptr->link[lr = 0];
-
}
-
prev->link[lr] = ptr->link[1]; // remove the item.
-
temp = ptr->key; // save the value of the just removed item.
-
delete ptr;
-
return temp; // return the value.
-
}
-
-
template <class Type>
-
int BinarySearchTree<Type>::height(bNode<Type>* const &ptr) const
-
{
-
if (ptr == NULL)
-
return 0;
-
int lt = height(ptr->link[0]), rt = height(ptr->link[1]);
-
if (lt < rt)
-
return 1 + rt;
-
return 1 + lt;
-
}
-
-
template <class Type>
-
bNode<Type>* BinarySearchTree<Type>::minmax(bNode<Type> *ptr, const bool &lr) const
-
{
-
// lr = zero min: lr = NOZero, max;
-
while (ptr->link[lr] != NULL)
-
ptr = ptr->link[lr];
-
return ptr;
-
}
-
-
template <class Type>
-
BinarySearchTree<Type>::BinarySearchTree()
-
{
-
// constructor
-
root = NULL;
-
count = 0;
-
}
-
-
template <class Type>
-
BinarySearchTree<Type>::~BinarySearchTree()
-
{
-
clear(root);
-
}
-
-
template <class Type>
-
void BinarySearchTree<Type>::clear()
-
{
-
clear(root);
-
root = NULL;
-
count = 0;
-
}
-
-
template <class Type>
-
bool BinarySearchTree<Type>::isEmpty() const
-
{
-
return (root == NULL);
-
}
-
-
template <class Type>
-
bool BinarySearchTree<Type>::insert(const Type &item)
-
{
-
if (root == NULL) {
-
root = new bNode<Type>;
-
root->key = item;
-
count++;
-
return true;
-
}
-
bool lr;
-
bNode<Type> *curr = root, *prev;
-
if (search(item, curr, prev, lr)) // overlap item is not allowed.
-
return false;
-
prev->link[lr] = new bNode<Type>;
-
prev->link[lr]->key = item;
-
count++;
-
return true;
-
}
-
-
template <class Type>
-
inline int BinarySearchTree<Type>::subNodes(bNode<Type>* const &ptr) const
-
{
-
if (ptr->link[1] != NULL) {
-
if (ptr->link[0] != NULL) // have two childs
-
return 2;
-
else
-
return 1; // have only one child
-
} else if (ptr->link[0] != NULL)
-
return 1; // have only one child.
-
else
-
return 0; // have no child
-
}
-
-
template <class Type>
-
bool BinarySearchTree<Type>::remove(const Type &item)
-
{
-
bool lr = 1;
-
bNode<Type> *curr = root, *prev;
-
if (!search(item, curr, prev, lr))
-
return false;
-
switch (int s = subNodes(curr)) {
-
// get the number of childs.
-
case 0:
-
case 1:
-
if (curr == root)
-
root = curr->link[(s > 0)];
-
else
-
prev->link[lr] = curr->link[(s > 0)];
-
delete curr;
-
break;
-
case 2:
-
curr->key = inOrder(curr); // replace the value with the next(neighbour) item's
-
}
-
count--;
-
return true;
-
}
-
-
template <class Type>
-
bool BinarySearchTree<Type>::search(const Type &item, Type *&ptr) const
-
{
-
bool found;
-
bNode<Type> *curr = root, *prev;
-
found = search(item, curr, prev, found);
-
ptr = &curr->key;
-
return found;
-
}
-
-
template <class Type>
-
Type BinarySearchTree<Type>::min() const
-
{
-
return minmax(root, 0)->key;
-
}
-
-
template <class Type>
-
Type BinarySearchTree<Type>::max() const
-
{
-
return minmax(root, 1)->key;
-
}
-
-
template <class Type>
-
int BinarySearchTree<Type>::size() const
-
{
-
return count;
-
}
-
-
template <class Type>
-
int BinarySearchTree<Type>::height() const
-
{
-
return height(root);
-
}
-
-
int main(int argc, char **argv)
-
{
-
BinarySearchTree<int> *bst = new BinarySearchTree<int>();
-
// 8
-
// / \
-
// 7 9
-
// / \ / \
-
// 5 4 10 11
-
bst->insert(8);
-
bst->insert(7);
-
bst->insert(9);
-
bst->insert(5);
-
bst->insert(4);
-
bst->insert(10);
-
bst->insert(11);
-
delete bst;
-
return 0;
-
}
Fast median search
-
#define ELEM_SWAP(a, b) {
-
register elem_type t = (a); (a) = (b); (b) = (t);
-
}
-
-
elem_type quickSelect(elem_type arr[], int n)
-
{
-
int low, high;
-
int median;
-
int middle, ll, hh;
-
-
low = 0;
-
high = n - 1;
-
median = (low + high) / 2;
-
for (; ;)
-
{
-
if (high < low) /* one element only */
-
return arr[median];
-
if (high == low + 1) {
-
/* Two elements only */
-
if (arr[low] > arr[high])
-
ELEM_SWAP(arr[low], arr[high]);
-
return arr[median];
-
}
-
-
/* Find median of low, median and high items; Swap into positin low */
-
middle = (low + high) / 2;
-
if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]);
-
if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]);
-
if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]);
-
-
/* Swap low item (now in position middle) into low + 1 */
-
ELEM_SWAP(arr[middle], arr[low+1]);
-
-
/* Nibble from each end towards middle, swapping items was stuck */
-
ll = low + 1;
-
hh = high;
-
for (;;)
-
{
-
do ll++; while (arr[low] > arr[ll]);
-
do hh--; while (arr[hh] > arr[low]);
-
-
if (hh < ll) break;
-
ELEM_SWAP(arr[ll], arr[hh]);
-
-
}
-
/* Swap middle item (in position low) back into position */
-
ELEM_SWAP(arr[low], arr[hh]);
-
/* Re-set actieve partition */
-
if (hh <= median)
-
low = ll;
-
if (hh >= median)
-
high = hh - 1;
-
}
-
}
-
-