数据结构 - 树 - 二叉查找树 - Binary Search Tree

1. 概念

二叉查找树(Binary Search Tree)也称有序二叉树(Ordered Binary Tree)、排序二叉树(Sorted Binary Tree)。

二叉查找树是java的 TreeSetTreeMap 类实现的基础。

二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n)。

2. 特点

  • 若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  • 若任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

  • 任意结点的左、右子树也分别为二叉查找树。

  • 没有键值相等的结点(no duplicate nodes)。

3. 实现

由于二叉查找树要求所有的节点都可以进行排序.所以编写时代码时需要一个 Comparable 泛型接口。

由于树的递归定义,二叉查找树的代码实现也基本上都是使用递归的函数,

3.1 继承关系


public class BinarySearchTree> 

3.2 定义节点

private static class TreeNode {

    T data;

    TreeNode left;

    TreeNode right;

    public TreeNode(T data) {
        this.data = data;
    }
}

3.3 属性

//根节点
private TreeNode root;

3.5 插入 void insert(T data)

public void insert(T data) {
    root = insert(data, root);
}

private TreeNode insert(T data, TreeNode node) {
    if (node == null) {
        return new TreeNode(data);
    }
    int result = node.data.compareTo(data);
    if (result == 0) {
        throw new IllegalArgumentException("has the same data :" + data.toString());
    }
    if (result > 0) {
        node.left = insert(data, node.left);
    } else if (result < 0) {
        node.right = insert(data, node.right);
    }
    return node;
}
数据结构 - 树 - 二叉查找树 - Binary Search Tree_第1张图片

3.6 查找最小值 T min()

public T min() {
    TreeNode node = min(root);
    return node == null ? null : node.data;
}

private TreeNode min(TreeNode node) {
    if (node == null) {
        return null;
    }
    if (node.left == null) {
        return node;
    }
    return min(node.left);
}

3.7 查找最大值 T max()

public T max() {
    TreeNode node = max(root);
    return node == null ? null : node.data;
}

private TreeNode max(TreeNode node) {
    if (node == null) {
        return null;
    }
    if (node.right == null) {
        return node;
    }
    return max(node.right);
}

3.8 是否包含元素 boolean contains(T data)

public boolean contains(T data) {
    return contains(data, root);
}

public boolean contains(T data, TreeNode node) {
    if (node == null) {
        return false;
    }
    int result = node.data.compareTo(data);
    if (result > 0) {
        return contains(data, node.left);
    } else if (result < 0) {
        return contains(data, node.right);
    }
    return true;
}
数据结构 - 树 - 二叉查找树 - Binary Search Tree_第2张图片

3.9 删除元素 void remove(T data)

在二叉查找树种,删除是最复杂的实现。涉及三种情况:

  • 被删除节点是树叶节点(没有子树):最简单,直接删除,将该节点置为null即可

  • 被删除节点有一个子节点(左子树或右子树):是该节点的父节点指向该节点的子节点(左或右). 见图1

  • 被删除节点有两个子节点:用其右子树中的最小值代替该节点上的值,删除其右子树上的最小值. 见图2

public void remove(T data) {
    remove(data, root);
}

public TreeNode remove(T data, TreeNode node) {
    if (data == null) {
        return null;
    }
    int result = node.data.compareTo(data);
    if (result > 0) {
        node.left = remove(data, node.left);
    } else if (result < 0) {
        node.right = remove(data, node.right);
    } else {
        //如果被删除节点有两个儿子
        if (node.left != null && node.right != null) { 
            TreeNode minRight = find(node.right, true);
            node.data = minRight.data; // 当前节点值被其右子树的最小值代替
            node.right = remove(minRight.data, node.right); // 将右子树的最小值删除
        } else if (node.left == null && node.right == null) {
            node = null; // 如果被删除的节点只是一个叶子
        } else if (node.left == null || node.right == null) { // 如果被删除节点只有一个儿子
            node = (node.left != null) ? node.left : node.right;
        }
    }
    return node;
}
数据结构 - 树 - 二叉查找树 - Binary Search Tree_第3张图片

你可能感兴趣的:(数据结构 - 树 - 二叉查找树 - Binary Search Tree)