二叉查找树,二叉搜索树,Binary Search Tree
二叉查找树性质:左孩子<双亲<右孩子
若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树。
没有键值相等的节点(no duplicate nodes)。
二叉查找树插入与删除
插入
1.若当前的二叉查找树为空,则插入的元素为根节点;
2.若插入的元素值小于根节点值,则将元素插入到左子树中;
3.若插入的元素值不小于根节点值,则将元素插入到右子树中。
删除
分三种情况进行处理:
1.p为叶子节点。
直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点)。
2.p为单支节点(即只有左子树或右子树)。
让p的子树与p的父亲节点相连,删除p即可(注意分是根节点和不是根节点)。
3.p的左子树和右子树均不空。
(找后继,次大值):找到p的后继y,因为y一定没有左子树,所以可以删除y,并让y的父亲节点成为y的右子树的父亲节点,并用y的值代替p的值;
二叉查找树实现
//BSTree.h
#ifndef BSTREE_HXX
#define BSTREE_HXX
#include <iostream>
using namespace std;
template <class T>
class BSTNode
{
public:
T key;
BSTNode *leftchild;
BSTNode *rigthchild;
BSTNode *parent;
BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):\
key(value),parent(),leftchild(l),right(r){}
};
template <class T>
class BSTree
{
private:
BSTNode<T> *root;
public:
BSTree();
~BSTree();
void preOrder();//先序遍历
void inOrder()://中序遍历
void postOrder();//后序遍历
BSTNode<T> * search(BSTNode<T> *tree,T key);//递归查找
BSTNode<T> * iterativeSearch(T key);//非递归查找
T minimum();//查找最小结点
T maximum();//查找最大结点
BSTNode<T> * successor(BSTNode<T> *x);//查找x的后继结点
BSTNode<T> * predecessor(BSTNode<T> *x);//查找x的前驱结点
void insert(T key);//插入
void remove(T key);//删除
void destroy();//销毁二叉树
}
#endif //BSTREE_HXX
//BSTree.cpp
#include "BSTree.h"
#include <iostream>
using namespace std;
template <class T>
BSTree<T>::BSTree():root(NULL)
{
}
template <class T>
BSTree<T>::~BSTree()
{
destroy();
}
template <class T>
void BSTree<T>::preOrder()
{
BSTNode<T> * tree = root;
if(tree != NULL)
{
cout<<tree->key<<" ";
preOrder(tree->leftchild);
preOrder(tree0>rightchild);
}
}
template <class T>
void BSTree<T>::inOrder()
{
BSTNode<T> * tree = root;
if(tree != NULL)
{
inOrder(tree->leftchild);
cout<<tree->key<<" ";
inOrder(tree0>rightchild);
}
}
template <class T>
void BSTree<T>::postOrder()
{
BSTNode<T> * tree = root;
if(tree != NULL)
{
postOrder(tree->leftchild);
postOrder(tree0>rightchild);
cout<<tree->key<<" ";
}
}
template <class T>
BSTNode<T> * BSTree<T>::search(BSTNode<T> *tree,T key)
{
tree = root;
if(tree == NULL || tree->key == key)
return tree;
if(key < tree->key)
return search(tree->leftchild,key);
if(key > tree->key)
return search(tree->rightchild,key);
}
template <class T>
BSTNode<T> * BSTree<T>::iterativeSearch(T key)
{
BSTNode<T> * tree = root;
while((tree != NULL) && (tree->key != key))
{
if(key < tree->key)
tree = tree->leftchild;
else
tree = tree->rightchild;
}
return tree;
}
template <class T>
T BSTree<T>::minimum()
{
BSTNode<T> * tree = root;
if(tree == NULL)
return NULL;
while(tree->leftchild != NULL)
tree = tree->leftchild;
return tree->key;
}
template <class T>
T BSTree<T>::maximum()
{
BSTNode<T> * tree = root;
if(tree == NULL)
return NULL;
while(tree->rightchild != NULL)
tree = tree->rightchild;
return tree->key;
}
//后继结点,次小结点
template <class T>
BSTNode<T> * BSTree<T>::successor(BSTNode<T> *x)
{
// 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
if(x->rightchild != NULL)
return minimum(x->rightchild);
// 如果x没有右孩子。则x有以下两种可能:
// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
// (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结
BSTNode<T> * p = x->parent;
while((p != NULL) && (x == p->rightchild))
{
x = p;
p = p->parent;
}
return p;
}
//前驱结点,次大结点
template <class T>
BSTNode<T> * BSTree<T>::predecessor(BSTNode<T> *x)
{
if(x->leftchild != NULL)
return minimum(x->leftchild);
BSTNode<T> * p = x->parent;
while((p != NULL) && (x == p->leftchild))
{
x = p;
p = p->parent;
}
return p;
}
template <class T>
void BSTree<T>::insert(T key)
{
BSTNode<T> * p = NULL;
BSTNode<T> * x = root;
while(x!=NULL)
{
p = x;
if(key < x->key)
x = x->leftchild;
else
x = x->rightchild;
}
BSTNode<T> * newNode = new BSTNode<T>;
newNode->key = key;
newNode->parent = p;
if(p == NULL)
root = newNode;
elseif(newNode->key < p->key)
p->leftchild = newNode;
else
p->rightchild = newNode;
}
template <class T>
void BSTree<T>::remove(T key)
{
BSTNode<T> * x = NULL;
BSTNode<T> * y = NULL;
BSTNode<T> * tree = root;
BSTNode<T> * removeNode = search(root,key);
if((removeNode->leftchild == NULL) || (removeNode->rightchild == NULL))
y = removeNode;
else
y = successor(removeNode);
if(y->leftchild != NULL)
x = y->leftchild;
else
x = y->rightchild;
if(x != NULL)
x->parent = y->parent;
if(y->parent == NULL)
tree = x;
elseif(y == y->parent->leftchild)
y->parent->leftchild = x;
else
y->parent->rightchild = x;
if(y != removeNode)
removeNode->key = y->key;
delete y;
}
template <class T>
void BSTree<T>::destroy(BSTNode<T> * tree)
{
tree = root;
if(tree == NULL)
return;
if(tree->leftchild != NULL)
return destroy(tree->leftchild);
if(tree->rightchild != NULL)
return destroy(tree->rightchild);
delete tree;
tree = NULL;
}