一、查找的一些问题
- 查找分为静态查找和动态查找,前者的查找内容本身和数量不发生改变,后者则会出现删除、插入等操作,对查找内容本身和数量造成影响。
- 那么针对动态查找的问题,二叉搜索树是一个较好的解决方法。
二、什么是二叉搜索树?
- 二叉搜索树是一颗二叉树,它可以为空,如果不为空的话需要满足以下性质:
- 非空左子树所有键值小于其根节点的键值
- 非空左子树所有键值大于其根节点的键值
- 左、右子树都是二叉搜索树
三、二叉搜索树可能包含的函数
function 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;
}
function AnotherFind(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
}
- 查找最大和最小元素(属于查找)
- 最大元素一定在树的最右分支的端节点上
- 最小元素一定在树的最左分支的端节点上
function MinFind(BinTree BST){
if(!BST)
return NULL;
else if(!BST->Left)
return BST
else
return MinFind(BST->Left)
}
function MaxFind(BinTree BST){
if(BST)
while(BST->Right)
BST = BST->Right;
return BST;
}
- 插入、删除
- 二叉搜索树的插入和删除的关键问题在于要找到需要修改的节点位置,这类似于查找的过程,可以采用与查找类似的方法。
- 删除操作存在三种情况:
- 要删除的节点是叶子节点
这种情况直接删除节点即可 - 要删除的节点有一个子节点与他链接
这种情况可将子节点连接至删除节点的父节点 - 要删除的节点有两个子节点与他链接
这种情况我们可以使用一个节点来替代被删除节点:右子树的最小元素或者左子树的最大元素
BinTree Insert(ElementType X,BinTree BST){
if(!BST){
BST = malloc(sizeof(struct TreeNode));
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;
}
BinTree Delete(ElementType X,Bintree BST){
BinTree Position;
if(!BST)
printf("未找到!");
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){
Position = MinFind(BST->Right);
BST->Data = Position->Data;
BST->Right = Delete(BST->Data,BST->Right);
}else{
Position = BST;
if(!BST->Left){
BST = BST->Right;
}else if(!BST->Right){
BST = BST->Left;
}
free(Position);
}
return BST;
}