1.存储结构(二叉链表)
#include <stdio.h>
#include <stdlib.h>
typedef struct bitnode
{
int data;
struct bitnode *lchild, *rchild;
}bitnode, *bitree;
2.二叉排序树查找算法
//递归查找二叉排序树t中是否存在key
status Search(bitree &t, int key, bitree f, bitree &p)//p指向数据元素的结点
//f指向其双亲结点,其初始调用值为NULL
{
if(!t) //若b是空树,则搜索失败
{
p = f
return 0;
}
else if(key==t->data)//若查找成功,则指针p指向该数据元素结点,并返回TRUE
{
p = t;
return 1;
}
else if(key < t->data)//若key小于t的根节点的数据域之值,则搜索左子树
return Search(t->lchild, key, t, p);
else
return Search(t->rchild, key, t, p);//搜索右子树
}
3.二叉排序树的插入算法
(1). 在查找的基础上
// 当二叉排序树T中不存在关键字等于key的数据元素时插入key
status Insert(bitree &t, int key)
{
bitree p, s;
if(!Search(t, key, NULL, p))//查找不成功
{
s = new bitnode;
s->data = key;
s->lchild = rchild = NULL;
if(!p) //若为空树,插入s为根节点
t = s;
else if(key < p->data)
p->lchild = s; //插入s为左子树
else
p->rchild = s; //插入s为右子树
return 1;
}
else
return 0; //树中已有关键字相同的结点,不再插入
}
(2). 直接插入法,不需要借助查找关键词
status Insert(bitree &t, int key)
{
if(t==NULL)//创建一个新的结点
{
t=new bitnode;
t->lchild=NULL;
t->rchild=NULL;
t->data=key;
}
else
{
if(key < t->data)
Insert (t->lchild,key);//插入key为左子树
else
Insert (t->rchild,key);//插入key为右子树
}
}
4. 二叉排序树的删除算法
二叉排序树的删除可分三种情况讨论:
(1)被删除的结点是叶子, 由于删去叶子结点不破坏整棵树的结构,只需修改其双亲结点的指针即可。
(2)被删除的结点只有左子树或者只有右子树,此时只需要将被删除结点的左子树或者右子树改为其双亲结点的左子树或者右子树即可。
(3)被删除的结点既有左子树,也有右子树,以其前驱替代该结点,再删除该前驱结点。
ps:寻找前驱结点的方法——找到当前结点的左孩子,一直向右遍历,即得当前结点的前驱结点。
//若二叉排序树t中存在关键字等于key的数据元素时,则删除该数据元素结点
status Delsearch(bitree &t, int key)
{
if(!t) //空树肯定不存在等于key的数据元素
return 0;
else
{
if(key == t->data) //找到关键字等于key的数据元素,执行删除操作
return Delete(t);
else if(key < t->data)
return Delsearch(t->lchild, key);//遍历左子树
else
return Delsearch(t->rchild, key);//遍历右子树
}
}
status Delete(bitree &t)//此时t代表被删结点
{
bitree q, s;
if(t->rchild == NULL)//右子树空则只需重接待删结点的左子树(待删结点是叶子也走此分支)
{
q = t;
t = t->lchild;
free(q);
}
else if(t->lchild == NULL)//左子树空则只需重接待删结点的右子树(待删结点是叶子也走此分支)
{
q = t;
t = t->rchild;
free(q);
}
else//左右子树均不空
{
q = t;
s = t->lchild; //转左
while(s->rchild)//向右走到尽头(找到待删结点的前驱结点)
{
q = s;
s = s->rchild;
}
t->data = s->data;//用被删结点前驱的值取代被删结点的值
if(q!=t)
q->rchild = s->lchild; // 重接q的右子树
else
q->lchild = s->lchild; // 重接q的左子树
free(s);
}
return 1;
}