二叉排序查找树
来自《大话数据结构》中的解释:
二叉排序树(Binary Sort Tree),又称二叉查找树,它或者是一个树,或者具有以下性质的二叉树:
- 若它的左子树不空,则左子树上所有节点的值均小于它根节点的值;
- 若它的右子树不空,则右子树上所有节点的值均大于它根节点的值;
- 它的左、右二叉树也分别为二叉排序树。
常用的二叉排序树抽象数据结构类型有:查找,插入,删除,遍历等操作。首先来构造一棵树:
typedef struct BiNode
{
int data; //节点的数据域.
struct BiNode * lchild, * rchild; //lchild指向左子树,rchild指向右子树.
}BiNode, *BiTree;
查找操作
先来看一下二叉排序树的查找操作:
//T表示树结构,key表示要查找的关键字,f一般默认值为NULL,*p为指向key节点的地址。
bool SearchBitree(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)
{
return SearchBitree(T->lchild, key, T, p);
}
else
{
return SearchBitree(T->rchild, key, T, p);
}
}
插入操作
bool InsertBST(BiTree *T, int key) //将数据插入到树中
{
BiNode *p;
if(!SearchBitree(*T, key, NULL, &p)) //如果查找不成功,执行插入操作.
{
BiTree pNew = (BiTree)malloc(sizeof(BiNode));
if(NULL==pNew)
{
printf("内存分配失败!");
}
pNew->data = key;
pNew->lchild = NULL;
pNew->rchild = NULL;
if(!p)
{
*T = pNew;
}
else if(key<p->data)
{
p->lchild = pNew;
}
else
{
p->rchild = pNew;
}
return true;
}
else
return false;
}
二叉排序树的遍历
二叉排序树因为是【左边的值<中间的值<右边的值】,所以用的是中序遍历,需要用到递归操作,代码如下:
void Traverse(BiTree T) //中序递归遍历二叉树
{
if (NULL == T)
return;
//中序排序:213,前序排序123,后序排序231.
Traverse(T->lchild); // 2
printf("%d ", T->data); // 1
Traverse(T->rchild); // 3
}
删除操作
bool Delete(BiTree *p)
{
BiTree q, s;
if((*p)->lchild == NULL)
{
q = *p;
*p = (*p)->rchild;
free(q);
}
else if((*p)->rchild == NULL)
{
q = *p;
*p = (*p)->lchild;
free(q);
}
else
{
q = *p;
s = (*p)->lchild;
while(s->rchild)
{
q = s;
s = s->rchild;
}
if(q!=*p)
q->rchild = s->lchild;
else
q->lchild = s->lchild;
}
return true;
}
bool DeleteBST(BiTree *T, int key) // 删除树中的数据
{
if(*T != NULL)
{
if(key == (*T)->data)
{
return Delete(T);
}
else if(key < (*T)->data)
{
return DeleteBST(&(*T)->lchild, key);
}
else
{
return DeleteBST(&(*T)->rchild, key);
}
}
else
{
printf("此树为空,删除失败!\n");
return false;
}
}
下面把整段代码附上:
#include<stdio.h>
#include<malloc.h>
typedef struct BiNode
{
int data;
struct BiNode * lchild, * rchild;
}BiNode, *BiTree;
bool Delete(BiTree *p)
{
BiTree q, s;
if((*p)->lchild == NULL)
{
q = *p;
*p = (*p)->rchild;
free(q);
}
else if((*p)->rchild == NULL)
{
q = *p;
*p = (*p)->lchild;
free(q);
}
else
{
q = *p;
s = (*p)->lchild;
while(s->rchild)
{
q = s;
s = s->rchild;
}
if(q!=*p)
q->rchild = s->lchild;
else
q->lchild = s->lchild;
}
return true;
}
bool DeleteBST(BiTree *T, int key) // 删除树中的数据
{
if(*T != NULL)
{
if(key == (*T)->data)
{
return Delete(T);
}
else if(key < (*T)->data)
{
return DeleteBST(&(*T)->lchild, key);
}
else
{
return DeleteBST(&(*T)->rchild, key);
}
}
else
{
printf("此树为空,删除失败!\n");
return false;
}
}
bool SearchBitree(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)
{
return SearchBitree(T->lchild, key, T, p);
}
else
{
return SearchBitree(T->rchild, key, T, p);
}
}
bool InsertBST(BiTree *T, int key) //将数据插入到树中
{
BiNode *p;
if(!SearchBitree(*T, key, NULL, &p))
{
BiTree pNew = (BiTree)malloc(sizeof(BiNode));
if(NULL==pNew)
{
printf("内存分配失败!");
}
pNew->data = key;
pNew->lchild = NULL;
pNew->rchild = NULL;
if(!p)
{
*T = pNew;
}
else if(key<p->data)
{
p->lchild = pNew;
}
else
{
p->rchild = pNew;
}
return true;
}
else
return false;
}
void Traverse(BiTree T) //中序递归遍历二叉树
{
if (NULL == T)
return;
Traverse(T->lchild);
printf("%d ", T->data);
Traverse(T->rchild);
}
int main(void)
{
BiNode * T = NULL;
int i;
int a[10] = {62,88,58,47,35,73,51,99,37,93};
for(i=0;i<10;i++)
{
InsertBST(&T, a[i]);
}
printf("删除前: \n");
Traverse(T);
printf("\n");
printf("删除后: \n");
DeleteBST(&T,62);
DeleteBST(&T,35);
DeleteBST(&T,73);
DeleteBST(&T,51);
DeleteBST(&T,93);
Traverse(T);
printf("\n");
return 0;
}
运行结果如下: