二叉排序树简介
二叉排序树满足以下性质
- 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 它的左、右子树也分别为二叉排序树。
二叉排序树存在的意义
当用线性表作为表的组织形式时,可以有三种查找法。其中以二分查找效率最高。但由于二分查找要求表中结点按关键字有序,且不能用链表作存储结构,因此,当表的插入或删除操作频繁时,为维护表的有序性,势必要移动表中很多结点。这种由移动结点引起的额外时间开销,就会抵消二分查找的优点。也就是说,二分查找只适用于静态查找表。若要对动态查找表进行高效率的查找,就可以使用二叉排序树。
二叉排序树的创建
要求:给定数组创建二叉排序树。
算法思路
遍历数组:
- 如果数为空,那么直接作为根节点放入。
- 如果比当前根节点大,向右递归创建。
- 如果比当前节点小,向左递归创建。
代码实现
public static BinaryTreeNode createTree(int[] arr) {
if (arr == null || arr.length == 0) return null;
BinaryTreeNode btn = new BinaryTreeNode(arr[0]);
for (int i = 1; i < arr.length; i++) {
create(btn, arr[i]);
}
return btn;
}
private static void create(BinaryTreeNode btn, int number) {
//不为空,判断大小
if (number > btn.value) {
if (btn.right == null) {
btn.right = new BinaryTreeNode(number);
return;
}
create(btn.right, number);
} else {
if (btn.left == null) {
btn.left = new BinaryTreeNode(number);
return;
}
create(btn.left, number);
}
}
二叉排序树的查找
算法思路
- 从根节点开始找
- 如果比根节点大,向右递归查找
- 如果比根节点小,向左递归查找
代码实现
public static BinaryTreeNode search(BinaryTreeNode btn, int num) {
BinaryTreeNode res = null;
if (num > btn.value) {
res = search(btn.right, num);
} else if (num < btn.value) {
res = search(btn.left, num);
} else {
res = btn;
}
return res;
}
二叉排序树的删除
算法思路
分为3种情况:
- 删除的是叶子节点
- 直接删除
- 删除的是只有一个子树的节点
- 删除现有的节点,将唯一的子节点接到父节点上。
- 删除的是有2个子树的节点
- 那么找到这个结点的右子树中的最小结点(此结点的左孩子一定为空),将最小结点的值赋给要删除的结点,然后删除最小结点。