二叉排序树(Binary Sort Tree),又被称为二叉查找树,它是一棵空树,或是具有以下性质的树:
①若它的左子树不为空,则它的左子树上的所有结点的值小于根节点的值;
②若它的右子树不为空,则它的右子树上的所有结点的值大于根节点的值;
③它的左右子树也是二叉排序树;
c++实现
#ifndef BST_H_
#define BST_H_
#include <stack>
using namespace std;
#define NULL 0
template<typename T>
struct BSTnode
{
T m_data; //关键字
BSTnode<T> *m_left; //左孩子指针
BSTnode<T> *m_right; //右孩子指针
};
template<typename T>
class BSTree
{
public:
BSTree(T data=NULL);
~BSTree();
bool SearchTree(BSTnode<T> *root, T key, BSTnode<T> *parent, BSTnode<T> *&place);
BSTnode<T> *& Getroot();
bool InsertTree(T key);
bool DeleteTree(BSTnode<T> * & place);
bool DeleteBST(BSTnode<T> *&root, T key);
void DestoryTree(BSTnode<T> *root);
void InOrderTraverse(BSTnode<T>* node);
//中序遍历
void InOrderTraverse2();
//非递归中序遍历
private:
BSTnode<T> *m_root;
};
template<typename T>
BSTree<T>::BSTree(T data)
{
m_root = new BSTnode<T>;
m_root->m_data = data;
m_root->m_left = m_root->m_right = NULL;
}
template<typename T>
BSTree<T>::~BSTree()
{
DestoryTree(m_root);
}
template<typename T>
bool BSTree<T>::SearchTree(BSTnode<T> *root, T key, BSTnode<T> *parent, BSTnode<T> *&place)
{
if (root==NULL)
{
place = parent;
return false;
}
else if (key == root->m_data)
{
place = root;
return true;
}
else if (key<root->m_data)
{
SearchTree(root->m_left, key, root, place);
}
else
{
SearchTree(root->m_right, key, root, place);
}
}
template<typename T>
BSTnode<T> *& BSTree<T>::Getroot()
{
return m_root;
}
template<typename T>
bool BSTree<T>::InsertTree(T key)
{
BSTnode<T> *p = NULL;
BSTnode<T> *s;
if (!SearchTree(Getroot(),key,NULL,p)) //查找不成功
{
s = new BSTnode<T>;
s->m_data = key;
s->m_left = s->m_right = NULL;
if (p == NULL)
{
exit(1);
}
else if (key<p->m_data)
{
p->m_left = s;
}
else
{
p->m_right = s;
}
return true;
}
else
{
return false; //该点已经存在
}
}
template<typename T>
bool BSTree<T>::DeleteBST(BSTnode<T> *&root, T key)
{
if (root == NULL)
{
return false;
}
else if (key == root->m_data)
{
return DeleteTree(root);
}
else if (key<root->m_data)
{
DeleteBST(root->m_left, key);
}
else
{
DeleteBST(root->m_right, key);
}
}
template<typename T>
bool BSTree<T>::DeleteTree(BSTnode<T> * & place)
{
BSTnode<T> *p,*s;
if (place->m_left==NULL)
{
p = place;
place = place->m_right;
delete p;
}
else if (place->m_right == NULL)
{
p = place;
place = place->m_right;
delete p;
}
else //左右子树都不为空
{
p = place;
s = place->m_left;
while (s->m_right!=NULL)
{
p = s;
s = s->m_right;
}
place->m_data = s->m_data;
if (p!=place)
{
p->m_right = s->m_left;
}
else
{
p->m_left = s->m_left;
}
delete s;
}
return true;
}
template<class T>
void BSTree<T>::DestoryTree(BSTnode<T> *root)
{
if (root != NULL)
{
DestoryTree(root->m_left);
DestoryTree(root->m_right);
delete root;
}
}
template<class T>
void BSTree<T>::InOrderTraverse(BSTnode<T>* node)
{
if (node == NULL)
{
return;
}
else
{
InOrderTraverse(node->m_left);
cout << node->m_data<<" ";
InOrderTraverse(node->m_right);
}
}
template<class T>
void BSTree<T>::InOrderTraverse2() //非递归方法
{
stack<BSTnode<T> *> temp;
BSTnode<T> *p = m_root;
temp.push(p);
while (p || temp.size())
{
while (p->m_left)
{
temp.push(p->m_left);
p = p->m_left;
}
while (temp.size())
{
p = temp.top();
temp.pop();
cout << p->m_data << " ";
p = p->m_right;
if (p)
{
temp.push(p);
break;
}
}
}
}
#endif
测试一下
#include <iostream>
#include <cstdlib>
#include "BST.h"
int main()
{
using namespace std;
int n;
cout << "The number input: ";
cin >> n;
int *temp = new int[n];
cout << "Enter all number separate by blank:" << endl;
for (int i = 0; i < n; i++)
{
cin >> temp[i];
}
BSTree<int> My(temp[0]);
for (int i = 1; i < n; i++)
{
My.InsertTree(temp[i]);
}
My.InOrderTraverse(My.Getroot());
cout <<endl<< "enter the num delete: ";
int m;
cin >> m;
My.DeleteBST(My.Getroot(),m);
My.InOrderTraverse2();
system("pause");
return 0;
}
排序二叉树的重点是查找,插入和删除都是基于递归查找而实现的,这里需要注意的有两个点
①在插入和删除中使用的指针参数不能是按值传递,必须是指针的引用,才能改变树的链接情况。
②是将私有部分的根结点作为引用参数时,不能将返回的指针作为引用,需要将根指针的引用作为参数方可。