若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势。
二分搜索树 - 不能存储重复的元素 容易产生极端情况(斜树)
定义二分搜索树的结点信息
private class Node {
public E e; //数据域
public Node left; //左孩子(当前Node结点左子树的根)
public Node right; //右孩子(当前Node结点右子树的根)
//public int count = 1; //记录元素出现的次数 默认1
public Node(E e) {
this.e = e;
left = null;
right = null;
}
@Override
public String toString() {
return e.toString();
}
}
添加元素方法(迭代)
public void add(E e) {
//添加的迭代思路
Node node = new Node(e);
if (isEmpty()) {
root = node;
size++;
}
Node cur = root;
while (true) {
//新元素比当前大 往右走
if (node.e.compareTo(cur.e) > 0) {
if (cur.right == null) {
cur.right = node;
size++;
break;
} else {
cur = cur.right;
}
//新元素比当前小 往左走
} else if (node.e.compareTo(cur.e) < 0) {
if (cur.left == null) {
cur.left = node;
size++;
break;
} else {
cur = cur.left;
}
} else {
break;
}
}
}
添加元素方法(递归)
public void add(E e) {
//递归的思路
root = add(root, e);
}
//在以node为根的树中 插入元素e 并返回新树的根
private Node add(Node node, E e) {
//从下一层向上一层
if (node == null) {
size++;
return new Node(e);
}
//当前层向下一层
if (e.compareTo(node.e) < 0) {
node.left = add(node.left, e);
} else if (e.compareTo(node.e) > 0) {
node.right = add(node.right, e);
}
//当前层向上一层
return node;
}
删除元素方法
public void remove(E e) {
root = remove(root,e);
}
//以node为根 删除元素e 并返回删除后新树的根
private Node remove(Node node, E e) {
if (node == null) {
return null;
}
if (e.compareTo(node.e) < 0) {
node.left = remove(node.left, e);
return node;
} else if (e.compareTo(node.e) > 0) {
node.right = remove(node.right,e);
return node;
} else { //找到了
//如果待删除的结点左边为空 则右子树直接上
if (node.left == null) {
Node rightNode = node.right; //此时右边可能空 可能非空
node.right = null;
size--;
return rightNode;
}
if (node.right == null) {
Node leftNode = node.left; //此时左边非空的
node.left = null;
size--;
return leftNode;
}
//左右都不为空 把右子树的最小值当成新树的根返回
Node successor = minimum(node.right);
successor.right = removeMin(node.right);
successor.left = node.left;
node.left = node.right = null;
return successor;
}
}
层序遍历-迭代方式
//层序遍历-迭代方式
public void levelOrder() {
LinkedList<Node> queue = new LinkedList<>();
if (isEmpty()) {
return;
}
queue.offer(root);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.println(cur.e);
if (cur.left != null) {
queue.offer(cur.left);
}
if (cur.right != null) {
queue.offer(cur.right);
}
}
}
前中后序遍历-递归方式
//前序遍历
public void preOrder() {
preOrder(root);
}
//前序遍历-递归方式 以node为根节点 前序遍历DLR
private void preOrder(Node node) {
if (node == null) {
return;
}
System.out.println(node.e);
preOrder(node.left);
preOrder(node.right);
}
//中序遍历
public void inOrder() {
inOrder(root);
}
//中序遍历-递归方式 以node为根节点 中序遍历LDR
private void inOrder(Node node) {
if (node == null) {
return;
}
inOrder(node.left);
System.out.println(node.e);
inOrder(node.right);
}
//后序遍历
public void postOrder() {
postOrder(root);
}
//后序遍历-递归方式 以node为根节点 后序遍历LRD
private void postOrder(Node node) {
if (node == null) {
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.println(node.e);
}
查看树中是否包含元素e
public boolean contains(E e) {
return contains(root,e);
}
//查看以node为根的二分搜索树中是否包含元素e
private boolean contains(Node node, E e) {
if (node == null) {
return false;
}
if (e.compareTo(node.e) < 0) {
return contains(node.left, e);
} else if (e.compareTo(node.e) > 0) {
return contains(node.right, e);
} else {
return true;
}
}
查找树中最大最小值-递归
//寻找二分搜索树中的最小值
public E minimum() {
if (isEmpty()) {
throw new IllegalArgumentException("bst is empty");
}
return minimum(root).e;
}
//以node为根节点 查找最小值所在的结点 - 递归
private Node minimum(Node node) {
if (node.left == null) {
return node;
}
return minimum(node.left);
}
//寻找二分搜索树中的最大值
public E maximum() {
if (isEmpty()) {
throw new IllegalArgumentException("bst is empty");
}
return maximum(root).e;
}
//以node为根节点 查找最大值所在的结点 - 递归
private Node maximum(Node node) {
if (node.right == null) {
return node;
}
return maximum(node.right);
}
删除树中最大最小值-递归
//删除最小值
public E removeMin() {
E ret = minimum();
root = removeMin(root);
return ret;
}
//以node为根 删除其中的最小值结点 返回删除后新树的根
private Node removeMin(Node node) {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
node.left = removeMin(node.left);
return node;
}
//删除最大值
public E removeMax() {
E ret = maximum();
root = removeMax(root);
return ret;
}
//以node为根 删除其中的最大值结点 返回删除后新树的根
private Node removeMax(Node node) {
if (node.right == null) {
Node leftNode = node.left;
node.left = null;
size--;
return leftNode;
}
node.right = removeMax(node.right);
return node;
}
迭代器实现
@Override
public Iterator<E> iterator() {
return new BinarySearchTreeIterator();
}
private class BinarySearchTreeIterator implements Iterator<E> {
private Iterator<E> it;
public BinarySearchTreeIterator() {
LinkedList<E> list = new LinkedList<>();
LinkedList<Node> stack = new LinkedList<>();
Node p = root;
while (p != null) {
stack.push(p);
p = p.left;
}
while (!stack.isEmpty()) {
Node cur = stack.pop();
list.offer(cur.e);
if (cur.right != null) {
Node n = cur.right;
while (n != null) {
stack.push(n);
n = n.left;
}
}
}
it = list.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public E next() {
return it.next();
}
}