特点
每个顶点总是大于它的左孩子,小于它的右孩子。
插入新结点:沿着根节点开始,key大于当前结点就往右子树搜,小于当前结点就往右子树搜,如果等于,说明已经有该结点,插入失败,否则,一直到叶子结点,将当前结点插入对应位置称为新的叶子。
删除结点:先找有无结点p,若无,删除失败。若有,分为三种情况:
p只有左孩子,将左孩子链接到p的父结点,删除p;
p只有右孩子,将右孩子链接到p的父结点,删除p;
p有两个孩子,找到p的左孩子的最右孙子,或者p的右孩子的最左孙子,根据二叉排序树的特点可以知道这两个点最接近p,用它替换p仍然可以保持二叉排序树特性,只要将结点的值替换即可,然后删除用来替换的结点(删除方法同前两种情况)。
#include<iostream>
using namespace std;
typedef struct BiTNode
{
int data;
BiTNode* lchild, * rchild;
}BiTNode,*BiTree;
//创建二叉排序树
void Insert(BiTree* T, int key) //单个结点的插入函数,递归实现
{
BiTree s;
if (*T == NULL) //为空,找到根结点,插入
{
s = (BiTree)malloc(sizeof(BiTNode));
s->data = key;
s->lchild = NULL;
s->rchild = NULL;
*T = s;
}
else if (key < (*T)->data)//要插入的值大于当前结点,往左子树搜
Insert(&((*T)->lchild), key);
else if (key > (*T)->data)//大于当前结点,往右子树搜
Insert(&((*T)->rchild), key);
}
void CreateBStree(BiTree* T)
{
int key;
*T = NULL;
int a[10] = { 35 ,23, 45, 27 ,19, 12, 56, 66 ,18 ,32 };
for(int i=0;i<10;i++)
{
Insert(T, a[i]); //调用插入结点函数
}
}
//前序遍历二叉树
void PreOrder(BiTree T)
{
if (T==NULL)
return;
cout << T->data << " ";
PreOrder(T->lchild);
PreOrder(T->rchild);
}
//查找
//T:当前结点,key:键值,f:根结点,p:用于返回查找到的数据
bool BST_Search(BiTree T, int key, BiTree f,BiTree* p)
{
if (!T)
{
*p = f;
return false;
}
else if (key == T->data)
{
*p = T;
return true;
}
else if (key < T->data)
BST_Search(T->lchild, key, T, p);
else
BST_Search(T->rchild, key, T, p);
}
bool BST_Insert(BiTree* T, int key)
{
BiTree p, s;
if (!BST_Search(*T, key, NULL, &p)) //查找不成功,返回p为最后一个比较的结点
{
s = (BiTree)malloc(sizeof(BiTNode)); //新的结点
s->data = key;
s->lchild = s->rchild = NULL;
if (!p) //返回空,排序树为空,s作为根结点
*T = s;
else if (key < p->data)
p->lchild = s;
else
p->rchild = s;
return true;
}
else
return false;
}
bool Delete(BiTree* p)
{
BiTree q, s;
if ((*p)->lchild == NULL) //p左空,连上右子树
{
q = (*p);
(*p) = (*p)->rchild;
free(q);
}
else if ((*p)->rchild == NULL) //p右空,连上左子树
{
q = (*p);
(*p) = (*p)->lchild;
free(q);
}
else //左右子树都不空
{
q = (*p); //q存找到的p左子最右孩子的前驱
s = (*p)->lchild; //s存p的左子树中的最右结点
while (s->rchild)
{
q = s; s = s->rchild;
}
(*p)->data = s->data; //用s替换p
if (q != (*p)) //此时s为q的左孩子,s无右孩子,把s的左孩子连到q的左子
q->rchild = s->lchild;
else //此时s为q的右孩子,s无右孩子,把s的左孩子连接到q的右子即可
q->lchild = s->lchild;
free(s);
}
return true;
}
bool BST_Delete(BiTree* T, int key) //删除结点p
{
BiTree p, q, s;
s = (BiTree)malloc(sizeof(BiTNode));
p = (BiTree)malloc(sizeof(BiTNode));
q = (BiTree)malloc(sizeof(BiTNode));
if (!T) //查找不成功
return false;
if ((*T)->data == key)
return Delete(T);
else if (key < (*T)->data)
BST_Delete(&(*T)->lchild, key);
else
BST_Delete(&(*T)->rchild, key);
}
int main()
{
BiTree T = NULL;
//T = (BiTree*)malloc(sizeof(BiTree));
int key = 18;
CreateBStree(&T);
cout << endl<<"删除"<<key<<"前" << endl;
PreOrder(T);
BST_Delete(&T,key);
cout << endl<<"删除"<<key<<"后" << endl;
PreOrder(T);
BST_Insert(&T, key);
cout << endl<<"插入"<<key<<"后"<<endl;
PreOrder(T);
return 0;
}
// 35 23 45 27 19 12 56 66 18 32 null