二叉搜索树
来源:互联网 发布:阿里云大厦有什么公司 编辑:程序博客网 时间:2024/06/09 23:18
最近在学习浙江大学的数据结构,整理如下
二叉搜索树(BST, Binary Search Tree)也称二叉排序树或二叉查找树
静态查找
一般是对于动态查找
二叉搜索树:一棵二叉树,可以为空,如果不为空,满足以下性质
1.非空左子树的所有键值小于其根节点键值
2.非空右子树的所有键值大于其根结点键值
3.左右子树都是二叉搜索树
树的实现
typedef int ElementType;typedef struct TreeNode *BinTree;typedef BinTree Position;struct TreeNode{ ElementType Data; BinTree Left; BinTree Right;};
二叉搜索树的操作
1.Find
查找某一已知元素
Position Find(ElementType X,BinTree BST){if(!BST) return NULL;if(X>BST->Data) return Find(X,BST->Right);else if(X<BST->Data) return Find(X,BST->Left);else return BST;};
对于这种尾递归,可以改为循环实现
Position Find(ElementType X,BinTree BST){ while(BST) { if(X>BST->Data) BST=BST->Right; else if(X<BST->Data) BST=BST->Left; else return BST; }; return NULL;};
查找该二叉树的最大最小值
BinTree FindMin(BinTree BST){if(!BST) return NULL;else if(!BST->Left) return BST; else return FindMin(BST->Left);};
同样,该查找的循环实现
BinTree FindMax(BinTree BST){ if(BST) while(BST->Right)BST=BST->Right; return BST;};
2.Insert
元素的插入操作和元素的查找类似
BinTree Insert(ElementType X,BinTree BST){if(!BST) { BST=malloc(sizeof(struct TreeNode)); if(!BST) exit(0);BST->Data=X;BST->Left=BST->Right=NULL;}else if(X<BST->Data) BST->Left=Insert(X,BST->Left);//对于元素接在节点域后面要通过递归返回地址实现else if(X>BST->Data) BST->Right=Insert(X,BST->Right); return BST;};
3.Delete
删除树的结点:
1.如果删除的是叶结点,将其父节点指向该节点指针置为NULL
2.如果删除的是只有一个子节点的节点,将该节点的父节点指针指向要删除节点的子节点
3.如果要删除的有两个自己节点,在该节点的左子树找到最大的元素(或者在右子树中找到最小的元素),将其替换掉该节点
BinTree Delete(ElementType X,BinTree BST){Position Temp;if(!BST); else if(X<BST->Data) BST->Left=Delete(X,BST->Left);//递归返回删除节点的子节点,接在父节点上else if(X<BST->Data) BST->Right=Delete(X,BST->Right); else if(BST->Left&&BST->Right)//左右子树都不空 { Temp=FindMin(BST->Right); BST->Data=Temp->Data; BST->Right=Delete(BST->Data,BST->Right);}else { Temp=BST; if(!BST->Left)BST=BST->Right;//左子树为空,将该指针指向其右子树 else if(!BST->Right)BST=BST->Left;//右子数为空,将该指针指向其左子树 free(Temp);}return BST;};
二 平衡二叉树
1.平衡二叉树
平衡因子(Balance Factor,简称BF):BF(T)=|hL-hR|。其中hL和hR分别为T的左右子树高度。
平衡二叉树(Balance Binary Tree)(AVL树):
树可以为空,如果树不为空,则满足性质:任意节点的左右子树高度差不超过1
平衡二叉树的实现
typedef struct AVLNode *Position;typedef Position AVLTree; /* AVL树类型 */struct AVLNode{ ElementType Data; AVLTree Left; AVLTree Right; int Height; /* 树高 */};
平衡二叉树的高度:
考虑高度为h的平衡二叉树最少需要的结点数: n(h)=n(h-1)+n(h-2)+1
类比斐波那契数列可得树结点的递推公式: n(h)=F(h+2)-1;
则n个结点对应树的最小高度为logn阶
2.平衡二叉树的操作
插入
在平衡二叉树的插入新的元素时,以前小于1的平衡因子会被破坏,所以需要对平衡二叉树做相应的调整
RR旋转
当插入的元素在被破坏结点的右子树的右子树上,即RR插入,需要做RR旋转
代码实现如下:
AVLTree SingleRightRotation ( AVLTree A ){/*注意:A必须有一个右子结点B*/ /* 将A与B做右单旋,更新A与B的高度,返回新的根结点B*/ AVLTree B= A->Right; A->Right=B->Left; B->Left=A; A->Height=Max(GetHeight(A->Left),GetHeight(A->Right))+1; B->Height=Max(GetHeight(B->Left),A->Height)+1; return B;}
LL旋转
当插入的元素在被破坏节点的左子树的左子树上,即LL插入,需要做LL旋转
代码实现如下:
AVLTree SingleLeftRotation ( AVLTree A ){ /* 注意:A必须有一个左子结点B */ /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */ AVLTree B=A->Left; A->Left=B->Right; B->Right=A; A->Height=Max(GetHeight(A->Left),GetHeight(A->Right))+1; B->Height=Max(GetHeight(B->Left),A->Height)+1; return B;}
LR旋转
当插入的元素在被破坏结点的左子树的右子树上,即LR插入,需要做LR旋转
实现如下:
AVLTree DoubleLeftRightRotation ( AVLTree A ){ /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C*/ /*将A、B与C做两次单旋,返回新的根结点C*/ /*将B与C做右单旋,C被返回*/ A->Left=SingleRightRotation(A->Left); /* 将A与C做左单旋,C被返回*/ return SingleLeftRotation(A);}
RL旋转
当插入的元素在被破坏结点的右子树的左子树上,即RL插入,需要做RL旋转
实现如下:
AVLTree DoubleRightLeftRotation ( AVLTree A ){ /*注意:A必须有一个右子结点B,且B必须有一个左子结点C*/ /*将A、B与C做两次单旋,返回新的根结点C*/ /*将B与C做左单旋,C被返回*/ A->Right=SingleLeftRotation(A->Rigth); /* 将A与C做左单旋,C被返回*/ return SingleRightRotation(A);}
则插入操作的具体实现如下
AVLTree Insert( AVLTree T, ElementType X ){/*将X插入AVL树T中,并且返回调整后的AVL树*/ if(!T) {/*若插入空树,则新建包含一个结点的树*/ T=(AVLTree)malloc(sizeof(struct AVLNode)); T->Data=X; T->Height=0; T->Left=T->Right=NULL; } else if(X<T->Data) { /*插入T的左子树*/ T->Left=Insert(T->Left,X); /*如果需要左旋*/ if(GetHeight(T->Left)-GetHeight(T->Right)==2) //判断平衡因子是否被破坏 if(X<T->Left->Data) T=SingleLeftRotation(T);/*判断是否需要左单旋*/ else T=DoubleLeftRightRotation(T);/*判断是否需要左-右双旋*/ } else if(X>T->Data) { /*插入T的右子树*/ T->Right=Insert(T->Right,X); /*如果需要右旋*/ if(GetHeight(T->Left)-GetHeight(T->Right)==-2) if(X>T->Right->Data) T=SingleRightRotation(T);/*右单旋*/ else T=DoubleRightLeftRotation(T);/*右-左双旋*/ }/*else X==T->Data,无须插入*//*更新树高*/T->Height=Max(GetHeight(T->Left),GetHeight(T->Right))+1;return T;}
阅读全文
0 0
- 【二叉搜索数】HDU3791二叉搜索树
- 二叉树--二叉搜索树
- 【二叉树】二叉搜索树
- 二叉树- 二叉搜索树
- 【搜索树】二叉搜索树
- 二叉搜索树BSTree
- 二叉搜索树
- 二叉搜索树
- 二叉搜索树
- 最优二叉搜索树
- 二叉搜索树
- 二叉搜索树
- HDOJ3791 二叉搜索树
- 二叉查找树搜索
- 二叉搜索树
- 二叉搜索树
- BST 二叉搜索树
- 二叉搜索树
- 我已经搬家啦
- D3基础构件
- Northcott Game (Nim博弈)
- MongoDB基本操作
- PHP 过滤器(Filter)
- 二叉搜索树
- [总结]操作系统真是博大精深(一)
- concurrent常用类(二)
- 北京二手房成交继续低迷 有豪宅每周降价300万
- PDF阅读编辑器中压缩PDF文档的能力杠杠的
- mybatis-generator通过JavaParser工具实现Java代码合并
- 为什么不能建立引用的数组?
- 杭电5248—序列变换,最基础的二分
- Android常见的上滑渐变显示标题栏