(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
现有,如下一棵二叉查找树。
(图1)
现在,若要删除图1中,任意节点,需要考虑如下三种情况:
(1)需要删除的节点下并没有其他子节点。
(2)需要删除的节点下有一个子节点(左或右)。
(3)需要删除的节点下有两个子节点(既左右节点都存在)。
第一种情况直接删除即可,下面,直接讨论第二种情况。
若我们要删除的是3号节点,由图1可以看到,它下面还有一个4号子节点。由下图2,可以看出,对于这种办法,我们只需要想办法,让5号节点的左子树的指针指向4就可以了。
(图2)
第三种情况,既我们要删除的节点下,有2个子节点。如图3,我们先在需要删除的节点的右子树中,找到一个最小的值(因为右子树中的节点的值一定大于根节点)。然后,用找到的最小的值与需要删除的节点的值替换。然后,再将最小值的原节点进行删除(图4)。
(图3)
(图4)
代码:
template<class T>
void BinarySearchTree<T>::remove(const T& value)
{
remove(value,m_pRoot);
}
template<class T>
void BinarySearchTree<T>::remove(const T& value, BinaryNode<T>* &t)
{
if(t == NULL)
return;
if ( value < t->m_element) //表示需要删除的节点在左子树
remove(value,t->m_pLeft);
else if(value > t->m_element)//表示需要删除的节点在右子树
remove(value,t->m_pRight);
else if(value == t->m_element)
{
if(t->m_pLeft != NULL && t->m_pRight != NULL)//找到需要删除的节点且节点下面有两个子节点
{
//先找到需要删除的节点下,右子树的最小的节点
//并将它的值赋值给需要删除的节点
t->m_element = findMin(t->m_pRight)->m_element;
//删除前面找到的最小的节点。
remove(t->m_element,t->m_pRight);
}
else//需要删除的节点下有一个子节点(左节点或者右节点)
{
BinaryNode<T>* oldNode = t;
t = (t->m_pLeft != NULL) ? t->m_pLeft : t->m_pRight;
delete oldNode;
}
}
}
完整测试代码:
// BinarySearchTree.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
/*
binary search tree,中文翻译为二叉搜索树、二叉查找树或者二叉排序树。简称为BST
一:二叉搜索树的定义
他的定义与树的定义是类似的,也是一个递归的定义:
1、要么是一棵空树
2、如果不为空,那么其左子树节点的值都小于根节点的值;右子树节点的值都大于根节点的值
3、其左右子树也是二叉搜索树
*/
enum ORDER_MODE
{ ORDER_MODE_PREV = 0,
ORDER_MODE_MID,
ORDER_MODE_POST
};
template<class T>
class BinaryNode
{
public:
T m_element; //节点的值
BinaryNode* m_pLeft; //左孩子节点指针
BinaryNode* m_pRight; //右孩子节点指针
BinaryNode(const T& value,BinaryNode* lt,BinaryNode* rt):m_element(value),m_pLeft(lt),m_pRight(rt)
{}
};
template<class T>
class BinarySearchTree
{
private:
BinaryNode<T>* m_pRoot;
public:
BinarySearchTree();
BinarySearchTree(const BinarySearchTree& rhs);
~BinarySearchTree();
const T& findMin() const;
const T& findMax() const;
bool contains(const T& value) const;
void printTree(ORDER_MODE eOrderMode = ORDER_MODE_PREV)const;
void makeEmpty();
void insert(const T& value);
void remove(const T& value);
private:
void insert(const T& value, BinaryNode<T>* &t);
void remove(const T& value, BinaryNode<T>* &t);
BinaryNode<T>* findMin(BinaryNode<T>* t)const;
BinaryNode<T>* findMax(BinaryNode<T>* t)const;
bool contains(const T& value, const BinaryNode<T>* t)const;
void makeEmpty(BinaryNode<T>* &pValue);
void printTreeInPrev(BinaryNode<T>* value)const;
void printTreeInMid(BinaryNode<T>* value)const;
void printTreeInPost(BinaryNode<T>* value)const;
};
template<class T>
BinarySearchTree<T>::BinarySearchTree()
{
m_pRoot = NULL;
}
template<class T>
BinarySearchTree<T>::BinarySearchTree(const BinarySearchTree& rhs)
{
m_pRoot = rhs.m_pRoot;
}
template<class T>
BinarySearchTree<T>::~BinarySearchTree()
{
makeEmpty();
}
/*
判断此二叉搜索树是不是包含元素value
*/
template<class T>
bool BinarySearchTree<T>::contains(const T& value)const
{
return contains(value,m_pRoot);
}
template<class T>
bool BinarySearchTree<T>::contains(const T& value, const BinaryNode<T>* t)const
{
if(t == NULL)
return false;
else if(value < t->m_element)
return contains(value, t->m_pLeft);
else if(value > t->m_element)
return contains(value, t->m_pRight);
else
return true;
}
/*
清空删除掉整个树
*/
template<class T>
void BinarySearchTree<T>::makeEmpty()
{
makeEmpty(m_pRoot);
}
template<class T>
void BinarySearchTree<T>::makeEmpty(BinaryNode<T>* &pValue)
{
if (pValue == NULL)
return;
makeEmpty(pValue->m_pLeft);
makeEmpty(pValue->m_pRight);
delete pValue;
pValue = NULL;
}
/*
查找二叉搜索树当中的最大值和最小值
*/
//找最小的
template<class T>
const T& BinarySearchTree<T>::findMin() const
{
return findMin(m_pRoot)->m_element;
}
template<class T>
BinaryNode<T>* BinarySearchTree<T>::findMin(BinaryNode<T>* t)const
{
if (t == NULL)
return NULL;
if(t->m_pLeft == NULL)
return t;
else
return findMin(t->m_pLeft);
}
//找最大的
template<class T>
const T& BinarySearchTree<T>::findMax() const
{
return findMax(m_pRoot)->m_element;
}
template<class T>
BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T>* t)const
{
if ( t == NULL)
return NULL;
if (t->m_pRight == NULL)
return t;
else
findMax(t->m_pRight);
}
/*
插入一个值
*/
template<class T>
void BinarySearchTree<T>::insert(const T& value)
{
insert(value,m_pRoot);
}
template<class T>
void BinarySearchTree<T>::insert(const T& value, BinaryNode<T>* &t)
{
if(t == NULL)
t = new BinaryNode<T>(value,NULL,NULL);
else if (value < t->m_element)
{
insert(value,t->m_pLeft);
}
else if(value > t->m_element)
{
insert(value,t->m_pRight);
}
else
{
cout<<"无法插入已经存在的值"<<endl;
}
}
/*
删除一个值(最复杂的地方)
*/
template<class T>
void BinarySearchTree<T>::remove(const T& value)
{
remove(value,m_pRoot);
}
template<class T>
void BinarySearchTree<T>::remove(const T& value, BinaryNode<T>* &t)
{
if(t == NULL)
return;
if ( value < t->m_element) //表示需要删除的节点在左子树
remove(value,t->m_pLeft);
else if(value > t->m_element)//表示需要删除的节点在右子树
remove(value,t->m_pRight);
else if(value == t->m_element)
{
if(t->m_pLeft != NULL && t->m_pRight != NULL)//找到需要删除的节点且节点下面有两个子节点
{
//先找到需要删除的节点下,右子树的最小的节点
//并将它的值赋值给需要删除的节点
t->m_element = findMin(t->m_pRight)->m_element;
//删除前面找到的最小的节点。
remove(t->m_element,t->m_pRight);
}
else//需要删除的节点下有一个子节点(左节点或者右节点)
{
BinaryNode<T>* oldNode = t;
t = (t->m_pLeft != NULL) ? t->m_pLeft : t->m_pRight;
delete oldNode;
}
}
}
/*
打印二叉搜索树
*/
template <class T>
void BinarySearchTree<T>::printTree(ORDER_MODE eOrderMode /*= ORDER_MODE_PREV*/) const
{
if (ORDER_MODE_PREV == eOrderMode)
printTreeInPrev(m_pRoot);
else if (ORDER_MODE_MID == eOrderMode)
printTreeInMid(m_pRoot);
else if (ORDER_MODE_POST == eOrderMode)
printTreeInPost(m_pRoot);
else
;//do nothing
}
template <class T>
void BinarySearchTree<T>::printTreeInPrev(BinaryNode<T>* t) const
{
if (t)
{
cout << t->m_element<<" ";
printTreeInPrev(t->m_pLeft);
printTreeInPrev(t->m_pRight);
}
}
template <class T>
void BinarySearchTree<T>::printTreeInMid(BinaryNode<T>* t) const
{
if (t)
{
printTreeInPrev(t->m_pLeft);
cout << t->m_element<<" ";
printTreeInPrev(t->m_pRight);
}
}
template <class T>
void BinarySearchTree<T>::printTreeInPost(BinaryNode<T>* t) const
{
if (t)
{
printTreeInPost(t->m_pLeft);
printTreeInPost(t->m_pRight);
cout << t->m_element<<" ";
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BinarySearchTree<int> binaryTree;
binaryTree.insert(7);
binaryTree.insert(2);
binaryTree.insert(3);
binaryTree.insert(4);
binaryTree.insert(10);
binaryTree.insert(8);
binaryTree.insert(11);
binaryTree.insert(12);
binaryTree.insert(13);
bool b = binaryTree.contains(1);
int x = binaryTree.findMin();
cout << b << " "<< x <<endl;
x = binaryTree.findMax();
cout << x <<endl;
binaryTree.remove(10);
binaryTree.printTree(ORDER_MODE_PREV);
cout <<endl;
binaryTree.printTree(ORDER_MODE_MID);
cout <<endl;
binaryTree.printTree(ORDER_MODE_POST);
cout <<endl;
getchar();
return 0;
}