二叉排序树(构造 +插入+删除+路径查找)

二叉排序树(构造 +插入+删除+路径查找):

二叉排序树的特点:左孩子的关键字小于父亲结点,右孩子的关键字大于父亲结点,然后不停的递归构造,构造过程中,满足以上特点。

树的 基本操作 在前面二叉树的介绍中提到,下面直接看程序代码:

代码如下:

#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
*/

程序运行如下:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值