- 定义
- 二叉排序树的查找
- 二叉排序树的插入
- 二叉排序树的构造
- 二叉排序树的删除
- 总结:
二叉排序树,又称二叉查找树 (BST)
一颗二叉树或者空二叉树,或者是具有如下性质的二叉树:
- 左子树上所有的结点的关键字均小于根节点的关键字。
- 右子树上所有的结点的关键字均大于根节点的关键字。
- 左子树和右子树有各是一颗二叉排序树。
二叉排序树的查找左子树结点值<根节点<右子树结点值
进行中序遍历,可以得到一个递增的有序序列
因此二叉排序树可用于元素的有序组织、搜索
左子树结点值<根节点值<右子树结点值
若树非空,目标值与根节点的值比较:
- 若相等,则查找成功。
- 若小于根节点,则在左子树上查找,否则在右子树上查找。
查找成功,返回结点指针;查找失败返回 NULL
#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
typedef struct BSTNode {
int key;
struct BSTNode *lChild;
struct BSTNode *rChild;
} BSTNode, *BSTree;
BSTNode *BST_Search(BSTree T, int key) {
while (T != NULL && key != T->key) {//若树空或等于根节点值,则结束循环
if (key < T->key) { //小于,则在左子树查找
T = T->lChild;
} else {//大于,则在右子树查找
T = T->rChild;
}
} return T;
}
BSTNode *BST_Search(BSTree T, int key) {
if (T == NULL) {
return NULL;
}
if (key==T->key) {
return T;
}
if (key>T->key) {
BST_Search(T->rChild, key);
}
if (keykey) {
BST_Search(T->lChild, key);
}
return NULL;
}
二叉排序树的插入
若原二叉排序树为空,则直接插入结点;否则,若关键字 k 小于根节点值,则插入到左子树,若关键字 k 大于根节点值,则插入到右子树。
int BSt_Insert(BSTree *T, int k) {
if (*T == NULL) {
BSTree cur = (BSTree) malloc(sizeof(BSTNode));
cur->key = k;
cur->rChild = NULL;
cur->lChild = cur->rChild;
(*T) = cur;
return 0;
}
BSTree tree = *T;
if (k == tree->key) {//存在相同结点,插入失败
return -1;
}
if (k > tree->key) {//大于,右子树去找
struct BSTNode *rChild = (*T)->rChild;
return BSt_Insert(&rChild, k);
} else {//小于,左子树去找
struct BSTNode *lChild = (*T)->lChild;
return BSt_Insert(&lChild, k);
}
}
二叉排序树的构造
按照数组依次构建二叉排序树 (使用上面 二叉排序树的插入来实现)
注意:不同关键字序列可能得到同款二叉排序树
void Create_BST(BSTree *T, int *arr, int length) {
(*T) = NULL;
int i = 0;
while (i < length) {
BST_Insert(T, arr[i]);
i++;
}
}
二叉排序树的删除
- 先 搜索 找到目标结点:
- 若被删除结点 z 是叶子节点,则直接删除,不会破坏二叉排序树的性质
- 若结点 z 只有一颗左子树或右子树,则让 z 的子树成为 z 父节点的子树,替代 z 的位置
- 若结点 z 有左右两颗子树,则令 z 的直接后继 (或直接前驱) 替代 z,然后从二叉排序树中删去这个直接后继 (或直接前驱),这样就转换成了第一或第二种情况。
- 使用直接后继来替换 z 结点
- z 的后继:z 的右子树最左下结点 (该节点一定没有左子树)
- 使用直接前驱来替换 z 结点
- z 的前驱:z 的左子树最右下结点 (该节点一定没有右子树)
- 使用直接后继来替换 z 结点
二叉排序树的中序遍历是有序的,且为升序。



