二叉查找树定义
二叉查找是是满足以下条件的二叉树
1.对于树中每个节点x,其左子树中所有节点的值均小于x;
2.对于树中每个节点x,其右子树中所有节点的值均大于x;
二叉查找树的基本操作
1.findMin 与findMax
(1) 要执行findMin,只要从根开始,一直沿着左节点往下找,直到子节点等于NULL为止。
(2)要执行findMax,只要从根开始,一直沿着右节点往下找,直到子节点等于NULL为止。
2.插入操作
插入的节点肯定是树的叶子,因此
(1)首先判断待插入值与当前节点值得大小关系
(2)如果小于当前节点值,则在左节点寻找插入点。
(3)如果大于当前节点,则在右节点寻找插入点。
(4)如果等于当前节点,则什么都不干
代码如下
//注意使用的是指针的引用,也可以使用指针的指针
template<class T>
void BinarySearchTree<T>::_insert(const T& x, BinaryNode<T>* & p)
{
if (p == NULL)
{
p = new BinaryNode<T>(x, NULL, NULL);
}
else if (x < p->value)
{
_insert(x, p->left);
}
else if (x > p->value)
{
_insert(x, p->right);
}
}
3.删除操作
分为3种情况
(1)如果待删除节点是叶子节点,则直接删除。
(2)如果待删除节点只有一个孩子,则用孩子节点替换要删除的节点。
(3)如果待删除节点有两个孩子,则以该节点右子树中最小的数据项替换该节点的数据项,再删除右子树中数据项最小的节点。
#include<iostream>
#include<vector>
#include<string>
using namespace std;
template<class T>
struct BinaryNode
{
public:
T value;
BinaryNode<T>* left;
BinaryNode<T>* right;
BinaryNode(const T& x, BinaryNode<T>* l,BinaryNode<T>*r) :value(x),left(l),right(r){}
};
template <class T>
class BinarySearchTree
{
public:
BinarySearchTree() :root(NULL){} //构造函数
//析构函数
~BinarySearchTree(){}
const BinaryNode<T>* findMin() const;
const BinaryNode<T>* findMax() const;
bool isEmpty() const{ return root == NULL ? true : false; };
void printTree() const{ _printTree(root); };
void insert(const T& x);
void remove(const T&x){ _remove(x, root); };
void makeEmpty(){ _makeEmpty(root); };
private:
BinaryNode<T>* root;
void _insert(const T&, BinaryNode<T>* & p);
void _remove(const T&, BinaryNode<T>*&);
BinaryNode<T>* _find(const T&, BinaryNode<T>*);
void _printTree(BinaryNode<T>*)const;
void _makeEmpty(BinaryNode<T>*&);
};
template<class T>
const BinaryNode<T>* BinarySearchTree<T>::findMin() const
{
if (root == NULL) return NULL;
auto p = root;
while (p->left != NULL)
{
p = p->left;
}
return p;
}
template<class T>
const BinaryNode<T>* BinarySearchTree<T>::findMax() const
{
if (root == NULL) return NULL;
auto p = root;
while (p->right != NULL)
{
p = p->right;
}
return p;
}
//注意使用的是指针的引用,也可以使用指针的指针
template<class T>
void BinarySearchTree<T>::_insert(const T& x, BinaryNode<T>* & p)
{
if (p == NULL)
{
p = new BinaryNode<T>(x, NULL, NULL);
}
else if (x < p->value)
{
_insert(x, p->left);
}
else if (x > p->value)
{
_insert(x, p->right);
}
}
template<class T>
void BinarySearchTree<T>::insert(const T&x)
{
_insert(x, root);
}
template<class T>
void BinarySearchTree<T>::_remove(const T& x, BinaryNode<T>*& p)
{
if (p == NULL)
{
return;
}
if (x < p->value)
{
_remove(x, p->left);
}
else if (x > p->value)
{
_remove(x, p->right);
}
else
{
if (p->left != NULL && p->right != NULL)
{
//如果待删除节点有两个子节点
//则用该节点的右子树最小节点替换待删除节点,并删除原来的最小节点
BinaryNode<T>*pTemp = p->right;//寻找右子树最小值
while (pTemp->left)
{
pTemp = pTemp->left;
}
p->value = pTemp->value;
delete pTemp;
pTemp = NULL;
}
else
{
BinaryNode<T>*pTemp = p;
p = (p->left != NULL) ? p->left : p->right;
delete pTemp;
}
}
}
template<class T>
BinaryNode<T>* BinarySearchTree<T>::_find(const T&x, BinaryNode<T>*p)
{
if (p == NULL)
{
return NULL;
}
else if (x < p->value)
{
return _find(x, p->left);
}
else if (x > p->value)
{
return _find(x, p->right);
}
else
{
return p;
}
}
template<class T>
void BinarySearchTree<T>::_printTree(BinaryNode<T>*p) const
{
if (p != NULL)
{
_printTree(p->left);
cout << p->value <<endl;
_printTree(p->right);
}
}
template<class T>
void BinarySearchTree<T>::_makeEmpty(BinaryNode<T>* &p)
{
if (p->left != NULL)
{
_makeEmpty(p->left);
}
if (p->right != NULL)
{
_makeEmpty(p->right);
}
delete p;
p = NULL;
}
int main()
{
BinarySearchTree<int> mySeachTree;
mySeachTree.insert(5);
mySeachTree.insert(7);
mySeachTree.insert(9);
mySeachTree.insert(0);
mySeachTree.insert(45);
mySeachTree.insert(33);
mySeachTree.insert(1);
mySeachTree.printTree();
cout << "min " << mySeachTree.findMin()->value << endl;
cout << "max " << mySeachTree.findMax()->value << endl;
mySeachTree.remove(33);
mySeachTree.printTree();
mySeachTree.makeEmpty();
system("pause");
return 0;
}