二叉排序树(构造 +插入+删除+路径查找):
二叉排序树的特点:左孩子的关键字小于父亲结点,右孩子的关键字大于父亲结点,然后不停的递归构造,构造过程中,满足以上特点。
树的 基本操作 在前面二叉树的介绍中提到,下面直接看程序代码:
代码如下:
#include <stdio.h>
#include <malloc.h>
#define max 50
typedef struct node{
int data;
struct node *lchild,*rchild;
}bstnode;//树的结构体类型
//定义的全局变量用来保存查找路径 ,d为下标
int path[max];
int d;
//构造树,插入关键字
bool insertbst(bstnode *&b, int k)
{
if(b==NULL) //找到一个为空的结点
{
b = (bstnode *)malloc(sizeof(bstnode));
b ->data = k;
b->lchild = b->rchild =NULL;
return true;
}
else if(b->data == k) return false;
else if(b->data > k) return insertbst(b->lchild, k);
else if(b->data <k) return insertbst(b->rchild, k);
}
//构造树
bstnode * createbst(int a[],int length)
{
bstnode *b;
for(int i=0; i<length; i++)
{
insertbst(b,a[i]);
}
return b;
}
//这里是要删除的结点的左右孩子都有的情况,第二个参数从左子树中找最大
void delete1(bstnode *p, bstnode *&r)
{
bstnode *q;
if(r->rchild!=NULL) r = r->rchild;
else{
p ->data = r->data;
//下面的删除操作
q = r;
r = r -> rchild;
free(q);
}
}
//删除
void deletes(bstnode *&b)
{
bstnode *p;
if(b->rchild == NULL)//结点只有左孩子
{
p = b;
b = b->lchild;
free(p);
}
else if(b->lchild == NULL)//结点只有右孩子
{
p = b;
b = b->rchild;
free(p);
}
else delete1(b,b->lchild); //结点左右孩子都有。
}
//在根据关键字删除结点的时候,有3中情况,一种删除的是叶子结点(没有左右孩子)
//二种是删除的结点只有左孩子或者只有右孩子
//三种是删除的结点左右孩子都有(这种情况,方法一就是在它的左子树中找到最大的结点值替换,然后在按照第二种情况,删除找到的结点)
bool deletebst(bstnode *&b,int k)
{
if(b==NULL) return false;
else{
//先找打结点
if(k < b->data)
{
return deletebst(b->lchild,k);
}
else if(k > b->data)
{
return deletebst(b->rchild,k);
}
else { //(k == b->data)
deletes(b);
return true;
}
}
}
//查询关键。
bool searchbst(bstnode *&b, int k)
{
if(b==NULL)
return false ;
else if(b->data == k)
{
path[d++] = b->data;
return true;
}
else if(b->data > k)
{
searchbst(b->lchild,k);
}
else if(b->data <k)
{
searchbst(b->rchild,k);
}
//这里是将每次经过的结点存入数组中.
path[d++] = b->data;
}
//输出构造的二叉排序树
void showbst(bstnode *p)
{
if(p!=NULL)
{
printf("%d",p->data);
if(p->lchild!=NULL || p->rchild != NULL)
{
printf("(");
showbst(p->lchild);
if(p->rchild != NULL) printf(",");
showbst(p->rchild);
printf(")");
}
}
}
//这里是判断是否找到路径的情况。
void fun(int k)
{
int flag = 0;
printf("查找并输出关键字为%d的路径: \n",k);
for(int i =0; i<d; i++)
{
if(path[i] == k)
{
flag = 1;
for(int j =d-1; j>0; j--) //这里不等于0,是由于不会将 “->”放在最后面.
printf("%d -> ", path[j]);
printf("%d \n",path[0]);
}
}
if(flag == 0) printf("找不到关键字!\n");
printf("\n");
}
int main()
{
bstnode *b;
int a[] = {4,9,0,1,8,6,3,5,2,7};
int length = sizeof(a)/sizeof(int);
b = createbst(a, length);
showbst(b);
printf("\n");
searchbst(b,35);
printf("\n");
fun(35);
searchbst(b,7);
printf("\n");
fun(7);
printf("\n删除关键字为7:\n");
deletebst(b,7);
showbst(b);
printf("\n");
return 0;
}
/*
4
0 9
1 8
3 7
2 5
6
*/
程序运行如下: