基本操作
定义存储结构
//定义存储结构
typedef struct
{
KeyType key;
OtherInfo info;
}ElemType;
typedef struct BSNode
{
ElemType data;
struct BSNode *lchild,*rchild;
}BSNode,*BSTree;
插入结点
//二叉排序树插入数据
void InsertBST(BSTree *T,ElemType e) //传入树根结点指针地址
{
if(*T==NULL) //树结点指针空
{
BSNode *S = (BSNode *)malloc(sizeof(BSNode)); //开辟新结点空间单元
S->data = e; //传入数据元素
S->lchild=S->rchild=NULL; //左右孩子指针域置空
*T = S; //传递指针(地址)
}
else if(e.key < (*T)->data.key) InsertBST(&(*T)->lchild,e); //数值小于根结点,插入到左子树上
else InsertBST(&(*T)->rchild,e); //否则右子树
}
创建二叉排序树
//创建二叉排序树
void CreateTree(BSTree *T)
{
ElemType e;
*T = NULL; //根节点指针置空
printf("请为二叉排序树输入排序树:");
scanf("%d",&e.key);
while(e.key !=0)
{
InsertBST(T,e); //循环插入数据
scanf(" %d",&e.key);
}
}
二叉排序树删除结点
//二叉排序树删除结点
void DeleteBST(BSTree *T,KeyType key)
{
BSNode *p=*T,*q,*s,*f=NULL;
//p指针用于记住给定值在二叉树结点的地址,q ,f记录给定值的双亲指针
while(p) //循环找到二叉树找到等于给定值的指针
{
if(p->data.key==key) break;
f=p;
if(p->data.key>key) p=p->lchild; //小于根结点的数值就往左子树找
else p=p->rchild; //否则往右子树找
}
if(!p) return; //找不到就结束函数调用
if((p->lchild)&&(p->rchild)) //找等于给定值结点,并有左右子树
{
q=p; //初始指向给定值
s=p->lchild; //指向给定值左孩子 往等于给定值结点的左子树找前驱结点
while(s->rchild)
{
q=s; //记录前驱节点的双亲结点的指针
s=s->rchild; //记录前驱结点指针
}
p->data = s->data; //将前驱节点的数值替代给定值结点里的数值
if(q!=p) q->rchild = s->lchild; //前驱结点的双亲并不是给定值指针 双亲的右孩子指针域指向前驱结点的左孩子
else q->lchild = s->lchild; //前驱结点的双亲是给定值指针 双亲的右孩子指针域(等于给定值结点)指向前驱结点的左孩子
free(s); //释放结点空间
return; //结束调用
}
else if(!p->rchild) //没有右子树
{
q=p;
p = p->lchild;
}
else //没有左子树
{
q=p;
p=p->rchild;
}
if(!f) *T=p; //等于给定值结点没有双亲结点时,它的左子孩子代替它的位置
else if(q==f->lchild) f->lchild = p; //等于给定值结点的指针等于双亲的左孩子时,双亲左孩子指针指向它的后继结点
else f->rchild=p; //双亲右孩子指针指向它后继结点
free(q); //释放 等于给定值结点
}
中序遍历
//中序遍历
void InOrder(BSTree T)
{
if(T)
{
InOrder(T->lchild); //递归输出 L
printf("%d ",T->data.key); //输出根 D
InOrder(T->rchild); //递归输出 R
}
}
测试代码整合
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int KeyType;
typedef int OtherInfo;
//定义存储结构
typedef struct
{
KeyType key;
OtherInfo info;
}ElemType;
typedef struct BSNode
{
ElemType data;
struct BSNode *lchild,*rchild;
}BSNode,*BSTree;
//二叉排序树插入数据
void InsertBST(BSTree *T,ElemType e) //传入树根结点指针地址
{
if(!(*T)) //树结点指针空
{
BSNode *S = (BSNode *)malloc(sizeof(BSNode)); //开辟新结点空间单元
S->data = e; //传入数据元素
S->lchild=S->rchild=NULL; //左右孩子指针域置空
*T = S; //传递指针(地址)
}
else if(e.key < (*T)->data.key) InsertBST(&(*T)->lchild,e); //数值小于根结点,插入到左子树上
else InsertBST(&(*T)->rchild,e); //否则右子树
}
//创建二叉排序树
void CreateTree(BSTree *T)
{
ElemType e;
*T = NULL; //根节点指针置空
printf("请为二叉排序树输入排序树:");
scanf("%d",&e.key);
while(e.key !=0)
{
InsertBST(T,e); //循环插入数据
scanf(" %d",&e.key);
}
}
//二叉排序树删除结点
void DeleteBST(BSTree *T,KeyType key)
{
BSNode *p=*T,*q,*s,*f=NULL;
//p指针用于记住给定值在二叉树结点的地址,q ,f记录给定值的双亲指针
while(p) //循环找到二叉树找到等于给定值的指针
{
if(p->data.key==key) break;
f=p;
if(p->data.key>key) p=p->lchild; //小于根结点的数值就往左子树找
else p=p->rchild; //否则往右子树找
}
if(!p) return; //找不到就结束函数调用
if((p->lchild)&&(p->rchild)) //找等于给定值结点,并有左右子树
{
q=p; //初始指向给定值
s=p->lchild; //指向给定值左孩子 往等于给定值结点的左子树找前驱结点
while(s->rchild)
{
q=s; //记录前驱节点的双亲结点的指针
s=s->rchild; //记录前驱结点指针
}
p->data = s->data; //将前驱节点的数值替代给定值结点里的数值
if(q!=p) q->rchild = s->lchild; //前驱结点的双亲并不是给定值指针 双亲的右孩子指针域指向前驱结点的左孩子
else q->lchild = s->lchild; //前驱结点的双亲是给定值指针 双亲的右孩子指针域(等于给定值结点)指向前驱结点的左孩子
free(s); //释放结点空间
return; //结束调用
}
else if(!p->rchild) //没有右子树
{
q=p;
p = p->lchild;
}
else //没有左子树
{
q=p;
p=p->rchild;
}
if(!f) *T=p; //等于给定值结点没有双亲结点时,它的左子孩子代替它的位置
else if(q==f->lchild) f->lchild = p; //等于给定值结点的指针等于双亲的左孩子时,双亲左孩子指针指向它的后继结点
else f->rchild=p; //双亲右孩子指针指向它后继结点
free(q); //释放 等于给定值结点
}
//中序遍历
void InOrder(BSTree T)
{
if(T)
{
InOrder(T->lchild); //递归输出 L
printf("%d ",T->data.key); //输出根 D
InOrder(T->rchild); //递归输出 R
}
}
int main()
{
BSTree T;
CreateTree(&T);
printf("第一次遍历二叉排序树: ");
InOrder(T);
printf("\n执行删除操作遍历二叉排序树:");
DeleteBST(&T,5); //删除给定值为 5的结点
InOrder(T);
return 0;
}
结果
分析
建立这样一棵二叉排序树