【二叉查找树的性质】
二叉查找树是满足以下条件的二叉树:
- 左子树上的所有节点值均小于根节点值
- 右子树上的所有节点值均不小于根节点值
- 左右子树也都是二叉查找树
- 不存在两个节点的值相等
【二叉查找树的插入、删除过程】
二叉查找树的插入过程如下:
1. 若当前的二叉查找树为空,则插入的元素为根节点
2. 若插入的元素值小于根节点值,则将元素插入到左子树中;若插入的元素值不小于根节点值,则将元素插入到右子树中。
二叉查找树的删除,分三种情况进行处理:
1. p为叶子节点,直接删除该节点,再修改其父节点的指针(注意分是根节点和不是根节点)
2. p为单支节点(即只有左子树或右子树)。让p的子树与p的父亲节点相连,删除p即可;(注意分是根节点和不是根节点)
3. p的左子树和右子树均不空。找到p的前驱s,s一定没有右子树,所以可以删除s,用s的值代替p的值,让s的父亲节点t成为s的左子树的父亲节点。
【代码实现】
//binarysearch.h代码
#ifndef binarysearch_h
#define binarysearch_h
template<class T> class BST;
template<class T>
class BSTnode
{
friend class BST<T>;
private:
T data;
BSTnode<T> *lchild;
BSTnode<T> *rchild;
};
template<class T>
class BST
{
public:
BST()
{
root=0;
}
void Insert(T item); //插入操作
void display();
void display(BSTnode<T> *currentnode,int i);//输出元素的位置
BSTnode<T> *Search(T item);
BSTnode<T> *Search(BSTnode<T> *currentnode,T item);//递归查找
BSTnode<T> *Search2(T item);//迭代查找
void Inorder();
void Inorder(BSTnode<T> *currentnode);//中序遍历
void delete_BST(T x);//删除操作
private:
BSTnode<T> *root;
};
//-------实现元素的按序插入-----------
template<class T>
void BST<T>::Insert(T item)
{
BSTnode<T> *p=root;
BSTnode<T> *q=0; //q为p的父节点
while(p)
{
q=p;
if(item<p->data)
{
p=p->lchild;
}
else if(item>p->data)
{
p=p->rchild;
}
else
{
// cout<<"不能重复插入"<<item<<endl;
return;
}
}
//找到插入位置q
p=new BSTnode<T>();
p->lchild=p->rchild=0;
p->data=item;
if(!root) //当为空树时
{
root=p;
}
else if(item<q->data)//作为q的左孩子
{
q->lchild=p;
}
else
{
q->rchild=p;//作为q的右孩子
}
}
//--------输出每个元素的位置---------
template<class T>
void BST<T>::display()
{
if(root)
display(root,1);
else
cout<<"这是一棵空树!"<<endl;
}
template<class T>
void BST<T>::display(BSTnode<T> *currentnode,int i)
{
cout<<"position "<<i<<":"<<currentnode->data<<endl;
if(currentnode->lchild)
display(currentnode->lchild,2*i);
if(currentnode->rchild)
display(currentnode->rchild,2*i+1);
}
//------二叉查找树的递归查找-----------
template<class T>
BSTnode<T>* BST<T>::Search(T item)
{
return Search(root,item);
}
template<class T>
BSTnode<T>* BST<T>::Search(BSTnode<T> *currentnode,T item)
{
if(!currentnode)
{
return 0; //没找到,返回空指针
}
if(currentnode->data==item)
return currentnode;
else if(currentnode->data>item)
return Search(currentnode->lchild,item);
else
return Search(currentnode->rchild,item);
}
//------二叉查找树的迭代查找-----------
template<class T>
BSTnode<T>* BST<T>::Search2(T item)
{
BSTnode<T>*p=root;
while(p)
{
if(p->data==item)
return p;
else if(p->data>item)
p=p->lchild;
else
p=p->lchild;
}
return 0;
}
//--------递归实现中序遍历---------
template<class T>
void BST<T>::Inorder()
{
cout<<"中序遍历为:";
Inorder(root);
cout<<endl;
}
template<class T>
void BST<T>::Inorder(BSTnode<T> *currentnode)
{
if(currentnode)
{
Inorder(currentnode->lchild);
cout<<currentnode->data<<" ";
Inorder(currentnode->rchild);
}
}
//-------------删除元素--------------
template<class T>
void BST<T>::delete_BST(T x)
{
BSTnode<T> * p,*q;
p=root;
//寻找被删元素
while(p)
{
if(x==p->data)//找到被删元素
{
break;
}
else if(x<p->data)//沿左子树找
{
q = p; //q记录p的父节点
p = p->lchild;
}
else //沿右子树找
{
q = p; //q记录p的父节点
p = p->rchild;
}
}
if(!p) //没找到
{
cout << "没有找到" << x << endl;
}
//p为待删除节点
if(p->lchild == 0 && p->rchild == 0) //情况1:p为叶子节点
{
if(p == root) //p为根节点
{
root = 0;
}
else if(q->lchild == p)//p为左子树
{
q->lchild =0;
}
else //p为右子树
{
q->rchild =0;
}
delete(p); //释放节点p
}
else if(p->lchild ==0 || p->rchild == 0) //情况2:p为单支子树
{
if(p == root) //p为根节点
{
if(p->lchild ==0)
{
root = p->rchild;
}
else
{
root = p->lchild;
}
}
else
{
if(q->lchild == p && p->lchild) //p是q的左子树且p有左子树
{
q->lchild = p->lchild; //将p的左子树链接到q的左指针上
}
else if(q->lchild == p && p->rchild) //p是q的左子树且p有右子树
{
q->lchild = p->rchild; //将p的右子树链接到q的左指针上
}
else if(q->rchild == p && p->lchild)//p是q的右子树且p有左子树
{
q->rchild = p->lchild; //将p的左子树链接到q的右指针上
}
else //p是q的右子树且p有右子树
{
q->rchild = p->rchild;//将p的右子树链接到q的右指针上
}
}
delete(p);
}
else //情况3:p的左右子树均不为空
{
BSTnode<T> *t,*s;
t=p;
s = p->lchild; //从p的左子节点开始
while(s->rchild) //找到p的前驱s(s一定没有右子树),即p左子树中值最大的节点
{
t = s; //t记录s的父节点
s = s->rchild;
}
p->data = s->data; //把节点s的值赋给p
if(t == p)
{
t->lchild = s->lchild;
}
else
{
t->rchild = s->lchild; //将p的前驱s的父节点指向s的左子树
}
delete(s);
}
}
#endif
//main.cpp
#include"binarysearch.h"
#include <iostream>
using namespace std;
int main()
{
BST<int> B1;
B1.Insert(5);
B1.Insert(3);
B1.Insert(11);
B1.Insert(8);
B1.Insert(3);
B1.display();
B1.Inorder();
// BSTnode<int> *p=B1.Search(3);
BSTnode<int> *p=B1.Search2(3);
if(p)
cout<<"找到3!"<<endl;
cout<<"删除5后:"<<endl;
B1.delete_BST(5);
B1.display();
B1.Inorder();
system("pause");
return 0;
}
【程序结果】
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-18 13:57:14