二叉查找树(Binary Sort Tree)又称为二叉查找树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者满足如下性质的二叉树:
(1) 若它的左子树非空:则左子树上所有节点的值均小于根节点的值。
(2)若它的右子树非空:则右子树上所有节点的值均大于根节点的值。
(3)左、右子树本身各是一棵二叉排序树。
下图就是一个简单的二叉排序树:
首先我们需要定义节点类以及二叉树排序类。这里二叉树的前序、中序、后序遍历的代码在上一篇博客中已经实现,这里不再复述,只给出创建、插入、查找的代码。
#include<iostream>
using namespace std;
template<class T> class BirnaryTree; //先声明一个类,一个二叉排序树类
template<class T>
class TreeNode //节点类定义
{
public:
TreeNode()
{
left=NULL;
right=NULL;
}
TreeNode(T num)//带参数的构造函数
{
data=num;
left=NULL;
right=NULL;
}
T data; //数据
TreeNode *left; //左子节点
TreeNode *right; //右子节点
};
template<class T>
class BirnaryTree //二叉树类定义
{
public:
BirnaryTree(T num[],int len); //构造函数
void insertNode(T data); //插入节点
TreeNode<T> *searchNode(T data); //查找节点
TreeNode<T> *searchNode(TreeNode<T> *currentNode,T data);
void PreOrder(); //前序遍历
void PreOrder(TreeNode<T> *currentNode);
void InOrder(); //中序遍历
void InOrder(TreeNode<T> *currentNode);
void PostOrder(); //后序遍历
void PostOrder(TreeNode<T> *currentNode);
public:
TreeNode<T> *root; //二叉树根节点
};
1、创建二叉排序树的方法(在构造函数中实现)
这里可以首先生成根节点,然后循环调用插入节点的方法对二叉树进行插入操作。
//在构造函数中创建二叉树
template<class T>
BirnaryTree<T>::BirnaryTree(T num[],int len)
{
root=new TreeNode<T>(num[0]);
for(int i=0;i<len;i++)
{
insertNode(num[i]);
}
}
这里insertNode(T data)插入节点的方法使用非递归方法,代码如下:
template<class T>
void BirnaryTree<T>::insertNode(T data)
{
TreeNode<T> *p=root;
TreeNode<T> *q=0;
while(p)
{
q=p;
if(data==p->data)
return;
else if(data < p->data)
p=p->left;
else
p=p->right;
}
//结束,说明找到一个位置(就是q),然后创建新节点,并将该节点连接到q的后面
TreeNode<T> *newNode=new TreeNode<T>(data);
if(!root)//如果是空树,那么插入的就是根节点
<span style="white-space:pre"> </span>root=newNode;
else if(newNode->data < q->data)//如果小于,则插入到左边;如果大于,则插入到右边
q->left=newNode;
else
q->right=newNode;
}
2、节点查找
注意这里两个成员函数TreeNode<T> *searchNode(T data)和TreeNode<T> *searchNode(TreeNode<T> *currentNode,T data)功能是不一样的,searchNode(T data)不断调用searchNode(TreeNode<T> *currentNode,T data)的方法,代码如下:
template<class T>
TreeNode<T>* BirnaryTree<T>::searchNode(T data)
{
return searchNode(root,data);
}
template<class T>
TreeNode<T>* BirnaryTree<T>::searchNode(TreeNode<T> *currentNode,T data)
{
if(data< currentNode->data)
{
if(currentNode->left==NULL)
return NULL;
return searchNode(currentNode->left,data);
}
else if(data > currentNode->data)
{
if(currentNode->right==NULL)
return NULL;
return searchNode(currentNode->right,data);
}
return currentNode;//如果相等,则返回currentNode
}
searchNode实现的步骤如下:
(1)如果data小于当前节点(currentNode)的值,且currentNode的左子树存在,则继续搜索currentNode的左子树,否则返回NULL。
(2)如果data大于当前节点(currentNode)的值,且currenNode的右子树存在,则继续搜索currenNode的右子树,否则返回NULL。
(3)如果data等于当前节点(currentNode)的值,则返回currentNode。
下面是主函数的测试代码:
int main()
{
int num[]={5,3,7,2,4,6,8,1};
BirnaryTree<int> tree(num,8);
TreeNode<int> *node;
//tree.PreOrder();
node=tree.searchNode(4);
if(node)
{
cout<<"成功找到所在节点,数值为:"<<node->data<<endl;
if(node->left)
cout<<"所在节点左节点数值为:"<<node->left->data<<endl;
else
cout<<"所在节点不存在左子树"<<endl;
if(node->right)
cout<<"所在节点右节点数值为:"<<node->right<<endl;
else
cout<<"所在节点不存在右子树"<<endl;
}
else
{
cout<<"没有找到"<<endl;
}
return 0;
}