二叉树的实现
原本的内容都放在二叉搜索树(BinarySearchTree)里面,今日重新看了一遍,强迫症让我把它分开了…以下~
package com.ssy.data_structure.tree;
import java.util.LinkedList;
import java.util.Queue;
public abstract class BinaryTree<E> implements Tree<E> {
protected Node<E> root;
protected int size;
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void clear() {
root = null;
size = 0;
}
@Override
public abstract void add(E e);
@Override
public abstract void remove(E e);
protected void elementNotNullCheck(E e) {
if (e == null) {
throw new IllegalArgumentException("element must be not null");
}
}
protected void preorderTraversal(BST.Visitor<E> visitor) {
if (visitor == null) return;
preorderTraversal(root, visitor);
}
private void preorderTraversal(Node<E> node, BST.Visitor<E> visitor) {
if (node == null || visitor.stop) return;
visitor.stop = visitor.visit(node.element);
preorderTraversal(node.left, visitor);
preorderTraversal(node.right, visitor);
}
protected void inorderTraversal(BST.Visitor<E> visitor) {
if (visitor == null) return;
inorderTraversal(root, visitor);
}
private void inorderTraversal(Node<E> node, BST.Visitor<E> visitor) {
if (node == null || visitor.stop) return;
inorderTraversal(node.left, visitor);
if (visitor.stop) return;
visitor.stop = visitor.visit(node.element);
inorderTraversal(node.right, visitor);
}
protected void postorderTraversal(BST.Visitor<E> visitor) {
if (visitor == null) return;
postorderTraversal(root, visitor);
}
private void postorderTraversal(Node<E> node, BST.Visitor<E> visitor) {
if (node == null || visitor.stop) return;
postorderTraversal(node.left, visitor);
postorderTraversal(node.right, visitor);
if (visitor.stop) return;
visitor.stop = visitor.visit(node.element);
}
protected void levelOrderTraversal(BST.Visitor<E> visitor) {
if (root == null || visitor == null) return;
Queue<Node<E>> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node<E> node = queue.poll();
boolean stop = visitor.visit(node.element);
if (stop) return;
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
protected boolean isComplete() {
if (root == null) {
return false;
}
Queue<Node<E>> queue = new LinkedList<>();
queue.offer(root);
boolean shouldBeLeaf = false;
while (!queue.isEmpty()) {
Node<E> node = queue.poll();
if (shouldBeLeaf && !node.isLeaf()) return false;
if (node.left != null) {
queue.offer(node.left);
} else if (node.right != null) {
return false;
}
if (node.right != null) {
queue.offer(node.right);
} else {
shouldBeLeaf = true;
}
}
return true;
}
protected int height() {
return height(root);
}
private int height(Node<E> node) {
if (node == null) return 0;
return 1 + Math.max(height(node.left), height(node.right));
}
protected Node<E> predecessor(Node<E> node) {
if (node == null) return null;
Node<E> predecessor = node.left;
if (predecessor != null) {
while (predecessor.right != null) {
predecessor = predecessor.right;
}
return predecessor;
}
while (node.parent != null && node == node.parent.left) {
node = node.parent;
}
return node.parent;
}
protected Node<E> successor(Node<E> node) {
if (node == null) return null;
Node<E> successor = node.right;
if (successor != null) {
while (successor.left != null) {
successor = successor.left;
}
return successor;
}
while (node.parent != null && node == node.parent.right) {
node = node.parent;
}
return node.parent;
}
protected static abstract class Visitor<E> {
boolean stop;
abstract boolean visit(E e);
}
protected static class Node<E> {
E element;
Node<E> left;
Node<E> right;
Node<E> parent;
public Node(E element, Node<E> parent) {
this.element = element;
this.parent = parent;
}
public boolean isLeaf() {
return left == null && right == null;
}
public int width() {
return (left == null ? 0 : 1) + (right == null ? 0 : 1);
}
}
}
二叉搜索树的实现
package com.ssy.data_structure.tree;
import java.util.Comparator;
public class BST<E> extends BinaryTree<E> {
private Comparator<E> comparator;
public BST() {
}
public BST(Comparator<E> comparator) {
this.comparator = comparator;
}
public void add(E e) {
elementNotNullCheck(e);
if (root == null) {
root = new Node<>(e, null);
} else {
Node<E> parent = parentNode(e);
Node<E> currentNode = new Node<>(e, parent);
linkNode(currentNode, parent);
}
size++;
}
private void linkNode(Node<E> currentNode, Node<E> parent) {
int result = compareNode(currentNode, parent);
if (result < 0) {
parent.left = currentNode;
} else if (result > 0) {
parent.right = currentNode;
} else {
parent.element = currentNode.element;
}
}
private Node<E> parentNode(E e) {
Node<E> node = root;
Node<E> parent = root;
while (node != null) {
int result = compareElement(e, node.element);
parent = node;
if (result < 0) {
node = parent.left;
} else if (result > 0) {
node = parent.right;
} else {
break;
}
}
return parent;
}
private int compareNode(Node<E> node1, Node<E> node2) {
E e1 = node1.element;
E e2 = node2.element;
return compareElement(e1, e2);
}
@SuppressWarnings("unchecked")
private int compareElement(E e1, E e2) {
if (comparator != null) {
return comparator.compare(e1, e2);
} else {
return ((Comparable<E>) e1).compareTo(e2);
}
}
public void remove(E e) {
remove(node(e));
}
private void remove(Node<E> node) {
if (node == null) return;
if (node.width() == 2) {
Node<E> succ = successor(node);
node.element = succ.element;
node = succ;
}
Node<E> childNode = node.left != null ? node.left : node.right;
if (childNode != null) {
childNode.parent = node.parent;
if (node.parent == null) {
root = childNode;
} else if (node == node.parent.left) {
node.parent.left = childNode;
} else {
node.parent.right = childNode;
}
} else if (node.parent == null) {
root = null;
} else {
if (node == node.parent.left) {
node.parent.left = null;
} else {
node.parent.right = null;
}
}
size--;
}
private Node<E> node(E e) {
Node<E> node = root;
while (node != null) {
int result = compareElement(e, node.element);
if (result == 0) return node;
node = result < 0 ? node.left : node.right;
}
return null;
}
public boolean contains(E e) {
return node(e) != null;
}
}
|