【知识点4】二叉查找树(BST)⭐⭐⭐⭐⭐

由于这部分是以前看多的,就直接贴书上的图了。。。

1. 二叉查找树的定义

在这里插入图片描述

2. 二叉查找树的基本操作——“增删改查建”

二叉查找树的基本操作有查找插入建树删除

2.1 查找操作

采用递归实现查找操作。

在这里插入图片描述

//search函数查找二叉查找树种数据域为x的结点
void search(node* root,int x){
	if(root == NULL){
		printf("search failed\n");
		return;
	}
	if(x == root->data){
		printf("%d\n",root->data);
	}else if(x < root->data){
		search(root->lchild,x);
	}else{
		search(root->rchild,x);
	}
} 

与普通的二叉树的查找函数不同,二叉查找树的查找在于对左右子树的选择递归

2.2 插入操作

在这里插入图片描述

  • 插入操作是基于查找操作的。
  • 注意传地址
//insert函数将在二叉树中插入一个数据域为x的新结点(注意参数root要加&)
void insert(node* &root,int x){
	if(root == NULL){
		root = newNode(x);
		return;
	}
	if(x == root->data){
		return;
	}else if(x < root->data){
		insert(root->lchild,x);
	}else{
		insert(root->rchild,x);
	}
} 

2.3 建树操作

在这里插入图片描述

//二叉查找树的建立
node* Create(int data[],int n){
	node* root = NULL;
	for(int i=0;i<n;i++){
		insert(root,data[i]);
	} 
	return root;
} 

在这里插入图片描述
注意:

  • 一棵二叉查找树的先序遍历得到的序列可以用来重新构建出这棵二叉查找树!!! ⭐⭐⭐⭐⭐ ‘
    由于二叉树的性质,所以我们可以确定左右子树,所以不需要中序遍历就能重构二叉查找树。

2.4 删除操作

采用递归实现删除操作。

在这里插入图片描述在这里插入图片描述

  • 寻找以root为根结点的树中的最大权值结点
  • 寻找以root为根结点的树中的最小权值结点
//寻找以root为根结点的树中的最大权值结点
node* findMax(node* root){
	while(root->rchild != NULL){
		root = root->rchild;
	}
	return root;
} 

//寻找以root为根结点的树中的最小权值结点
node* findMin(node* root){
	while(root->lchild != NULL){
		root = root->lchild;
	}
	return root;
} 

注意,删除操作也是使用递归的方式写的。
注意:在下面描述的 x待删除的结点的值。删除操作把 查找元素 x删除元素x 结合在了一起。
在这里插入图片描述
在这里插入图片描述

//删除以root为根结点的树中权值为x的结点
void deleteNode(node* &root,int x){
	if(root == NULL)
		return;		//不存在权值为x的结点
	if(root->data == x){	//找到欲删除结点 
		if(root->lchild == NULL && root->rchild == NULL){
			root = NULL;
		}else if(root->lchild != NULL){
			node* pre = findMax(root->lchild);
			root->data = pre->data;
			deleteNode(root->lchild,pre->data);
		}else{
			node* next = findMin(root->rchild);
			root->data = next->data;
			deleteNode(root->rchild,next->data); 
		} 
	}else if(root->data > x){
		deleteNode(root->lchild,x);
	}else{
		deleteNode(root->rchild,x);
	} 
} 

优化
在这里插入图片描述在这里插入图片描述

3. 二叉查找树的性质⭐⭐⭐⭐⭐

  1. 通过使用本节中定义的构树函数create()读入一棵二叉查找树的先序遍历得到的序列可以用来重新构建出这棵二叉查找树!!! ⭐⭐⭐⭐⭐ 不要傻乎乎的去使用传统先序+中序的方法
    参考例题是这道——⭐PAT A1135 Is It A Red-Black Tree
    然而事实证明,如果建树的过程是一个一个 insert() 进行的,这种建树方法称为 在线建树 ,而如果直接使用前序序列一次性进行建树,则成为 离线建树 ,由于在线建树每次都会有大量的重复的查找操作,因此时间复杂度非常高,最坏为 O ( N 2 ) O(N^2) O(N2)!而离线建树的时间复杂度为 O ( N ) O(N) O(N),因此,以后还是使用离线建树比较好!即还是使用传统先序+中序的方法更好!!!
    参考例题是这道——⭐⭐⭐⭐⭐PAT A1143 Lowest Common Ancestor

  2. 中序遍历得到有序结果在这里插入图片描述在这里插入图片描述

4. 题型训练

  1. 【PAT A1043】Is It a Binary Search Tree
  2. 【PAT A1064】Complete Binary Search Tree
  3. 【PAT A1099】Build A Binary Search Tree
  4. 二叉搜索树——浙大10年(错题)
  5. 二叉排序树——华科05年
  6. 二叉排序树02——华科
  7. LeetCode 230. Kth Smallest Element in a BST
  8. 删除结点——LeetCode 450. Delete Node in a BST
  9. 二分与二分查找树——LeetCode 109. Convert Sorted List to Binary Search Tree
  10. PAT A1115 Counting Nodes in a BST
  11. ⭐PAT A1135 Is It A Red-Black Tree
  12. ⭐⭐⭐⭐⭐PAT A1143 Lowest Common Ancestor

5. 参考文档

  1. 算法笔记
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值