二叉搜索树
Posted 思而不学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉搜索树相关的知识,希望对你有一定的参考价值。
查找问题:
- 静态查找与动态查找
- 针对动态查找,数据如何组织?
二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树
二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质:
1.非空左子树的所有键值小于其根结点的键值。
2.非空右子树的所有键值大于其根结点的键值。
3.左、右子树都是二叉搜索树。
二叉搜索树操作的特别函数:
Position Find(ElementType X, BinTree BST):从二叉搜索树BST中查找元素X,返回其所在结点的地址
Position FindMin(BinTree BST):从二叉搜索树BST中查找并返回最小元素所在的结点的地址
Position FindMax(BinTree BST):从二叉搜索树BST中查找并返回最大元素所在的结点的地址
BinTree Insert(ElementType X, BinTree BST)
BinTree Delete(ElementType X, BinTree BST)
二叉搜索树的查找操作:Find
- 查找从根结点开始,如果树为空,返回NULL
- 若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:
- 若X小于根结点键值,只需在左子树中继续搜索;
- 若果X大于根结点的键值,在右子树中进行继续搜索;
- 若两者比较结果是相等,搜索完成,返回指向此结点的指针
1 Position Find(ElementType X, BinTree BST) 2 { 3 if(!BST) return NULL; /* 查找失败 */ 4 if(X > BST->Data) 5 return Find(X, BST->Right); /* 在右子树中继续查找 */ 6 else if(X < BST->Data) 7 return Find(X, BST->Left); /* 在左子树中继续查找 */ 8 else 9 return BST; /* 查找成功,返回结点的找到结点的地址 */ 10 }
由于非递归函数的执行效率高,可将"尾递归”函数改为迭代函数
1 Position IterFind(ElementType X, BinTree BST) 2 { 3 while(BST) { 4 if(X > BST->Data) 5 BST = BST->Right; /* 在右子树中继续查找 */ 6 else if(X < BST->Data) 7 BST = BST->Left; /* 在左子树中继续查找 */ 8 else 9 return BST; /* 查找成功,返回结点的找到结点的地址 */ 10 } 11 return NULL; /* 查找失败 */ 12 }
查找效率取决于树的高度
查找最大和最小元素
- 最大元素一定是在树的最右分枝的端结点上
- 最小元素一定是在树的最左分支的端结点上
1 Position FindMin(BinTree BST) 2 { 3 if(!BST) return NULL; 4 else if(!BST->Left) 5 return BST; 6 else 7 return FindMin(BST->Left); 8 } 9 10 Position FindMax(BinTree BST) 11 { 12 if(!BST) return NULL; 13 else if(!BST->Right) 14 return BST; 15 else 16 return FindMax(BST->Right); 17 } 18 19 Position FindMin(BinTree BST) 20 { 21 if(BST) 22 while(BST->Left) BST = BST->Left; 23 return BST; 24 } 25 26 Position FindMax(BinTree BST) 27 { 28 if(BST) 29 while(BST->Right) BST = BST->Right; 30 return BST; 31 }
二叉搜索树的插入
分析:关键是要找到元素应该插入的位置,可以采用与Find类似的方法。
1 BinTree Insert(ElementType X, BinTree BST) 2 { 3 if(!BST) { 4 BST = (BinTree)malloc(sizeof(struct TreeNode)); 5 BST->Data = X; 6 BSt->Left = BST->Right = NULL; 7 } else { 8 if(X < BST->Data) 9 BST->Left = Insert(X, BST->Left); 10 else if(X > BST->Data) 11 BST->Right = Insert(X, BST->Right); 12 } 13 return BST; 14 }
二叉搜索树的删除
考虑三种情况:
- 要删除的是叶节点:直接删除,并再修改其父结点指针--置为NULL
- 要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点
- 要删除的结点有左、右两颗子树:用另一结点替代被删除结点:右子树的最小元素或者左子树的最大元素
- 取右子树中的最小元素替代
- 取左子树中的最大元素替代
1 BinTree Delete(ElementType X, BinTree BST) 2 { 3 Position Tmp; 4 if(!BST) printf("要删除的元素未找到"); 5 else if(X < BST->Data) 6 BST->Left = Delete(X, BST->Left); 7 else if(X > BST->Data) 8 BST->Right = Delete(X, BST->Right); 9 else 10 if(BST->Left && BST->Right) { 11 Tmp = FindMin(BST->Right); 12 BST->Data = Tmp->Data; 13 BST->Right = Delete(BST->Data, BST->Right); 14 } else { 15 Tmp = BST; 16 if(!BST->Left) 17 BST = BST->Right; 18 else if(!BST->Right) 19 BST = BST->Left; 20 free(Tmp); 21 } 22 return BST; 23 }
以上是关于二叉搜索树的主要内容,如果未能解决你的问题,请参考以下文章
代码随想录Day20-Leetcode654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树