二叉搜索树
利用二叉树搜索树(BST,Binary Search Tree),提高查找效率。设左儿子的节点值<父节点值<右儿子节点值
,在树中搜索X
,每遇到一个节点,将X
的值和节点值做比较,若X
较小,去左子树继续查找;若X
较大,去右子树继续查找;直至全部节点比较完毕或查找到元素。
查找操作Find
Position Find(ElementType X, BinTree BST){
if(!BST) return NULL; // 查找失败
if(X < BST -> Data){
return Find(BST -> Left);
}else if(X > BST -> Data){
return Find(BST -> Right);
}else{
return BST; // BST -> Data == X
}
}
上述方法中有尾递归,即递归的调用出现在函数末尾,本例是在return
语句。可以将尾递归函数更改为迭代函数。
Position IterFind(ElementType X, BinTree BST) {
while(BST) {
if(X < BST -> Data){
BST = BST -> Left;
}else if(X > BST -> Right){
BST = BST -> Right;
}else{
return BST;
}
}
return NULL; // 查找失败
}
如果树“不平衡”,比如所有节点没有右儿子,那么N
个节点构成的数的深度是N-1
,此时查找次数达不到理想的log(N)
。
插入操作Insert
- 如果树空,新建节点,给新节点赋值,返回指向该新节点的指针。
- 如果插入值比根节点小,去左子树插值。
- 如果插入值比根节点大,去右子树插值。
BinTree Insert(ElementType X, BinTree BST){
if(!BST){
BST = malloc(sizeof(struct TreeNode));
BST -> Data = X;
BST ->left = NULL;
BST -> Right = NULL;
}else if(X < BST -> Data){
BST -> Left = Insert(X, BST -> Left);
}else(X > BST -> Data){
BST -> Right= Insert(X, BST -> Right);
}
return BST;
}
这个函数和搜索有点像,但是多了一个返回值。返回的节点会被赋给父节点的左儿子或右儿子,继而,更新过后(已经插入新节点)的子树会“连”回根节点,一层层向上……
删除操作Delete
- 查找到该元素
- 分情况
1.被删的节点是叶节点,直接让它的父节点指向它的指针为null
2.被删的节点只有一个儿子,,让它的父节点指向它的儿子
3.被删的节点左右子树都非空,转化为第二种情况:在左子树中找到最大值(没有右儿子)或在右子树中找到最小值(没有左儿子),用最值节点代替被删节点,然后删除最值节点。
平衡二叉树
树的形状影响搜索效率。
定义平衡因子(Balance Factor,BF):BF(T) = hL - hR
,其中hL
、hR
分别是左右子树高度。
平衡二叉树(Balanced Binary Tree,AVL Tree):
空树,或者
对任一节点,有|BT(T)| <= 1
。
平衡二叉树高度
节点数为n
,最大高度O(logn)
,证明:利用斐波那契数列。