二叉排序树
1.二叉排序树定义
二叉排序树(BST),也称二叉查找树,亦称二叉搜索树。BST是一颗空树,或具有如下性质的非空二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
由此定义可知,BST是一个递归的数据结构,且BST中没有键值相等的节点。如果我们采用中序遍历,即可得到一个键值递增序列
2.二叉排序树查找
步骤:
1)若BST非空,根结点的关键字值等于查找的关键字,成功。
2)查找的关键字值小于根结点的关键字值,递归查左子树。
3)查找的的关键字值根结点的关键字值,递归查右子树。
Node *BST_Search(Node *T,ElemType key,Node *&p){
//查找函数返回关键词为key的节点指针,如不存在,返回NULL
p=NULL; //p指向查找节点的双亲,用与查找和删除节点
while(T!=NULL && T->data!=key){
p=T;
if(T->data >key) T=T->lchild;
else T=T->rchild;
}
return T;
}
3.二叉排序树的插入
BST作为一种动态集合,其特点是结构不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定的节点时进行插入。
步骤:若原BST为空,则直接插入节点,若关键字等于根节点关键字返回插入失败。若关键字小于根节点关键字,则插入左子树中,否则,插入右子树中。
bool BST_Insert(Node *root,ElemType key){
if(root==NULL){ //原树为空
root=new Node;
root->data=key;
root->lchild=root->rchild=NULL
return true;
}
else if(key==root->data) return false;
else if(key<root->data)
return BST_Insert(root->lchild,key);//插入root的左子树
else
return BST_Insert(root->rchild,key);//插入root的右子树
}
4.二叉排序树的构造
void Creat_BST(Node *root,vector<int> &v){
root=NULL;
int len=v.size();
for(int i=0;i<len;i++){
BST_Insert(root,v[i]);
}
}
5.二叉排序树的删除
(1)若待删除节点z是叶子节点,则直接delete
(2)若节点z只有一颗左子树或者右子树,则让z的子树成为父节点的子树,代替z位置
(3)若节点z有左,右子树,令z的直接前驱(或直接后继)替代z,然后再从二叉排序树中删去它的直接前驱(或直接后继),这样转化为第一种情况
*思考:现在我们来想这样一个问题,若在二叉树中删除并插入某节点,得到的二叉树是否和原来相同?
显然,删除节点,既可以删掉叶子节点,也可以删除根节点,还可以删除其他节点,只需要在删除节点后进行适当的调整即可(满足BST定义),而插入节点总是插入叶子位置,因此若在二叉树中删除并插入某节点,再次到的二叉树大多和原来的结构不同
6.代码模块
#include <iostream>
#include<vector>
using namespace std;
#define Element int
struct Node
{
int data;
Node *lchild, *rchild;
};
bool BST_Insert(Node * &root, Element key){
if(root==NULL) { // 空树
root = new Node;
root->data = key;
root->lchild = root->rchild = NULL;
return true;
}
if(key == root->data) // BST中不能有相等的值
return false;
if(key < root->data) //插左子树
return BST_Insert(root->lchild, key);
return BST_Insert(root->rchild, key); //插右子树
}
// 建立BST
void CreateBST(Node * &root, vector<int> &v)
{
root = NULL;
for(int i = 0; i <v.size(); i++){
BST_Insert(root, v[i]);
}
}
Node *BST_Search(Node *T,Element key,Node *&p){
//查找函数返回关键词为key的节点指针,如不存在,返回NULL
p=NULL; //p指向查找节点的双亲,用与查找和删除节点
while(T!=NULL && T->data!=key){
p=T;
if(T->data >key) T=T->lchild;
else T=T->rchild;
}
return T;
}
// 中序遍历,可得递增序列
void InOrder(Node *root){
Node *T=root;
if(T){
InOrder(T->lchild);
cout << T->data<<" ";
InOrder(T->rchild);
}
}
int main(){
int n;
cin>>n;
vector<int>v(n);
for(int i=0;i<n;i++){
cin>>v[i];
}
Node *T;
CreateBST(T,v);
cout<<"输出中序遍历:"<<endl;
InOrder(T);
cout<<endl<<"输出v[0]节点:"<<endl;
Node *p=BST_Search(T,v[0],p);
cout<<p->data <<endl;
cout<<"请输入要插入元素n:"<<endl;
cin>>n;
BST_Insert(T,n);
InOrder(T);
cout << endl;
return 0;
}
测试运行结果: