一、定义
二叉排序树(二叉搜索树 BST)
左子树所有结点关键字 < 根结点关键字
右子树所有结点关键字 > 根结点关键字
左右子树也都是二叉排序树
不含重复关键字
二、核心性质
中序遍历 = 递增有序序列
查找、插入、删除时间:平均 O(logn),最坏 O(n)(斜树)
适合动态查找:频繁插入、删除
三、查找操作
规则
key == 根:查找成功
key < 根:查左子树
key > 根:查右子树
递归代码
typedef struct BSTNode{
int key;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
// 查找
BSTNode* BST_Search(BSTree T, int key){
if(!T || T->key == key)
return T;
if(key < T->key)
return BST_Search(T->lchild,key);
else
return BST_Search(T->rchild,key);
}
四、插入操作
规则
树空 → 新建结点作根
key 小于当前结点 → 往左找空位置插入
key 大于当前结点 → 往右找空位置插入
重复元素不插入
// 插入
int BST_Insert(BSTree *T, int key){
if(!*T){
// 新建结点
*T = (BSTree)malloc(sizeof(BSTNode));
(*T)->key = key;
(*T)->lchild = (*T)->rchild = NULL;
return 1;
}
if(key == (*T)->key)
return 0; // 重复,插入失败
else if(key < (*T)->key)
return BST_Insert(&(*T)->lchild,key);
else
return BST_Insert(&(*T)->rchild,key);
}
五、删除操作
分三种情况:
叶子结点:直接删除
只有左 / 右单孩子:孩子直接顶替被删结点
左右都有孩子
找左子树最右结点(前驱) 或 右子树最左结点(后继) 顶替
再删除该前驱 / 后继结点
六、构造二叉排序树
依次将序列每个元素 逐个插入 即可。
七、复杂度总结
平均:查找 / 插入 / 删除 O(log 2 n)
最坏(单斜树):O(n)
中序遍历一定升序