二叉查找树

7 篇文章 0 订阅
5 篇文章 0 订阅

                                           二叉查找树

  • 定义:又称为是二叉排序树(Binary Sort Tree)或二叉搜索树。

         二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:

  1) 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  2) 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

  3) 左、右子树也分别为二叉排序树;

  4) 没有键值相等的节点。

  • 特色:1.对二叉排序树中序遍历便可得到有序数列(相当于对数组进行二叉排序)

                2.  二叉查找树的高度决定了二叉查找树的查找效率

 

  • 顾名思义二叉排序保证有序,它可不跟 '老婆饼' 一样狡猾  So,建立·插入·删除时都要有序

  • ---------------------------------相关操作 -------------------------------

                                             (1)查找:

  这里介绍两种方式 ---->        a.递归查找  :运用的是尾递归,可将为递归函数改为迭代函数 

Tree FindNode(Tree root,Elemtype e){
		if(root==NULL){
		return NULL;   //查找失败 
		}
		if(e<root->data){   //如果查找值<当前节点值,就去他的左子树继续查找 
		FindNode(root->lchild,e);
		} 
		else if(e>root->data){ //如果查找值>当前节点值,就去他的右子树继续查找
		FindNode(root->rchild,e);
		}
		else{
			printf("\n已找到罪犯节点\n"); 
		return root;   //如果e刚好等于当前节点值  就返回当前节点 
		}
}

                                                   b.非递归(迭代查找)           

Tree Find(Tree root,Elemtype e){
	while(root){
		if(e<root->data){   //如果查找值<当前节点值,就向左子树移动 
		root=root->lchild;
		} 
		else if(e>root->data){ //如果查找值>当前节点值,就向右子树移动 
		root=root->rchild;
		}
		else{
				printf("已找到罪犯节点");
		return root;   //如果e刚好等于当前节点值  就返回当前节点 
		}
	}
	return NULL;
}

                                            (2) 查找最大最小节点

                                                         ( 这里也是两种<迭代&&递归>方式 )

【注】最左(右)边的节点就是整棵二叉排序树的最小(大)节点

/递归查询最左(小)节点 
Tree Findmin(Tree root){
	if(!root){
		printf("\n未找到最小节点\n");
		return NULL; //如果是空树就返回NULL; 
	}else if(!root->lchild){
	return root;//最左,出口(左到没有左孩子) 
	}else{
	return Findmin(root->lchild);   //向左子树继续查找 
	}	
}
//	迭代查询最右(大)节点	
Tree Findmax(Tree root){
	if(root){
		while(root->rchild){
			root=root->rchild;
		}
	}
	return root;
}	

                                              (3)插入节点

                                        【注】(先查找节点的合适位置,要记得返回插入位置!)

   步骤:           1. 若当前的二叉查找树为空,则插入的元素为根节点;
                         2.若插入的元素值小于根节点值,则将元素插入到左子树中;
                         3.若插入的元素值不小于根节点值,则将元素插入到右子树中。

Tree InsertNode(Tree &root,Elemtype e){
	if(!root){
		//创建新节点 
		root=(Tree)malloc(sizeof(Tnode));
		root->data=e;
		root->lchild=root->rchild=NULL;
	}
	else{   //找插入位置 
			if(e< root->data){
			root->lchild=InsertNode(root->lchild,e);	
			}	
			else if(e> root->data){
			root->rchild=InsertNode(root->rchild,e);
			}
    }
    return root;
}	

                                              (4)删除节点

删除单支节点
删除双孩节点

 分析:             1.若删除节点为叶子节点  直接删除节点,再修改父节点指针   
                         2.若删除节点p为单支节点,让p的子树与p的父节点相连,删除p即可
                         3.若删除节点有左右孩子,就比较麻烦,有两种解决方案 : 
                                                               a.用有右子数的最小节点代替删除节点
                                                               b.用左子树的最大节点代替删除节点 

Tree DeleteNode(Tree &root,Elemtype e){
	Tree tmp;
	if(!root){
		printf("\n未找到删除节点\n");
	}
	else if(e<root->data){  //若e<当前节点数值就去左子树递归删除 
	   DeleteNode(root->lchild,e);
	}else if(e>root->data){   //若e>当前节点数值就去右子树递归删除 
	   DeleteNode(root->rchild,e);	
	}else //若找到删除节点 
	{
		if(root->lchild && root->rchild)//  如果是双孩子节点
		{
			  tmp=Findmin(root->rchild);//tmp暂时保存右子数最小节点 
			  root->data=tmp->data; //数据替换 
			  root->rchild=DeleteNode(root->rchild,root->data);//再去右子数删除那个最小节点 
		} 
		else{  
			tmp=root;
			if(!root->lchild){  //若是只有右孩子的单支节点 
				root=root->rchild;
			}else if(!root->rchild){  //若是只有左孩子的单支节点 
				root=root->lchild;
			}
			free(tmp);
		} 
	}
	return root;
}

                                              (4)创建二叉排序树

  • 创建的过程就是不断地递归插入节点

void CreateFindTree(Tree &root){    
 Elemtype data[7] = {45,20,53,48,12,21,90};
    for(int i=0;i<7;i++){
        InsertNode(root,data[i]);
    } 
                  
} 

                                          (5)中序遍历(输出有序序列)

void print(Tree root)
{
    if(root!=NULL)
    {
        print(root->lchild);
        printf("%d ",root->data);
        print(root->rchild);
    }
 } 

测试程序(AC):

#include<stdio.h>
#include<malloc.h> 
#define N 100

typedef int Elemtype;
//定义 
typedef struct Tnode{
	Elemtype data;
	struct Tnode *lchild,*rchild;
}Tnode,*Tree; 

int main(){
	int e;  Tree T=NULL,p;	
	CreateFindTree(T); 
	print(T); 
	p=FindNode(T,20);   //p=Find(T,20); 
	printf(",数据是%d\n",p->data);
	DeleteNode(T,20);
	print(T);
	p=Findmin(T);
	printf("\n最小节点的数据是%d\n",p->data);
	p=Findmax(T);
	printf("\n最大节点的数据是%d\n",p->data);
}
  • 运行结果:

  • 正经致谢:

     

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值