【数据结构】二叉搜索树的概念和常见操作

独自空忆成欢 提交于 2020-02-16 19:36:00

什么是二叉搜索树?

我们把一般的查找操作分为两类,静态查找和动态查找。在静态查找中有一种很快的查找方法(二分查找时间复杂度为O( log(n) )。它之所以可以将时间复杂度降的这么低,是因为在查找之前对数据进行了顺序的排序。在查找时查找的顺序是固定的,是一个判定树一样的结构。把一个线性的查找过程转换成了一个类似树的查找过程。查找效率就是树的高度。从此我们得到启示:在查找时为什么不能把数据直接用二叉树的结构存储。比起线性结构树的动态性更强,它的插入删除操作更加方便。这样就形成了二叉搜索树。
二叉搜索树定义
一颗二叉树,它可以为空,如果不为空,满足下边的性质:
(1)非空左子树的所有节点的值,都小于根节点的值。
(2)非空右子树的所有节点的值,都大于根节点的值。
(3)左右子树都是二叉搜索树。
这样在查找的时候,从根节点找,如果小于去左子树找,如果大于去右子树找。

二叉搜索树的常见操作:

//从二叉搜索树中找到元素data,并返回该节点的地址,如果找不到返回NULL;
Binary_Tree* Find(Binary_Tree* BST,Elementype data)//从搜索二叉树中BST中,找到最小值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Min(Binary_Tree* BST)//从搜索二叉树中BST中,找到最大值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Max(Binary_Tree* BST)
//从二叉搜索树插入一个节点
Binary_Tree* Insert( Binary_Tree* BST, Elementype data )//从二叉搜索树删除一个节点
Binary_Tree* Delete( Binary_Tree* BST, Elementype data )

具体操作:

#include<stdio.h>
#include<stdlib.h>
#define Elementype char
typedef struct Binary_Tree{
	Elementype data;
	struct Binary_Tree* L_child;
	struct Binary_Tree* R_child;
}Binary_Tree;
//从二叉搜索树中找到元素data,并返回该节点的地址,如果找不到返回NULL;
Binary_Tree* Find(Binary_Tree* BST,Elementype data){
	if(BST == NULL){//找不到返回NULL
		return NULL;
	}else if(BST ->data == data){
		return BST;
	}else if(data < BST ->data){
		Find(BST ->L_child,data);
	}else if(data > BST ->data){
		Find(BST ->R_child,data);
	}
}
//从搜索二叉树中BST中,找到最小值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Min(Binary_Tree* BST){
	if(BST == NULL){//树为空
		return NULL;
	}else if(BST ->L_child){
		Find_Min(BST ->L_child);
	}else{
		return BST;
	}
}
//从搜索二叉树中BST中,找到最大值data并返回该节点的地址(如果树为空,返回NULL)
Binary_Tree* Find_Max(Binary_Tree* BST){
	if(BST == NULL){//树为空
		return NULL;
	}else if(BST ->R_child){
		Find_Max(BST ->R_child);
	}else{
		return BST;
	}
}
Binary_Tree* Insert( Binary_Tree* BST, Elementype data ){//从二叉搜索树插入一个节点
	if(BST){//树不为空
		if(data < BST ->data){//要插入的值小于该节点的值
			BST ->L_child = Insert(BST ->L_child,data);
		}else if(data > BST ->data){//要插入的值大于该节点的值
			BST ->R_child = Insert(BST ->R_child ,data);
		}
	}else{//树为空
		BST = (Binary_Tree*)malloc(sizeof(Binary_Tree));
		BST ->data = data;
		BST ->L_child = BST ->R_child = NULL;
	}
	return BST;
}
Binary_Tree* Delete( Binary_Tree* BST, Elementype data ){//二叉搜索树删除一个节点
	Binary_Tree* tem = NULL;
	if(BST == NULL){
		printf("删除的节点不在树中");
	}else{
		if(data < BST ->data){
			BST ->L_child = Delete(BST ->L_child,data);
		}else if(data > BST ->data){
			BST ->R_child = Delete(BST ->R_child,data);
		}else{
			if(BST ->L_child && BST ->R_child){//左右子树都存在
				tem = Find_Max(BST ->R_child);//右子树找出最大值节点的地址
				BST ->data = tem ->data;
				Delete(BST ->R_child,tem ->data);//删除右子树的最大值节点;
			}else{
				if(BST ->L_child){
					tem = BST ->L_child;
				}else{
					tem = BST ->R_child;
				}
				free(BST);
				BST = tem;
			}
		}
	}
	return BST;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!