二叉查找(搜索)树
二叉查找树(Binary Search Tree,简称BST)是一棵二叉树,它的左子节点的值比父节点的值要小,右节点的值要比父节点的值大。
在理想的情况下,二叉查找树增删查改的时间复杂度为O(logN)(其中N为节点数),最坏的情况(线性)下为O(N)。它的高度决定了它的查找效率,当它的高度为logN+1时,我们就说二叉查找树是平衡的。
上代码,难理解的地方有注释:
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* @ClassName Binaryintree类
* @Author whw
* @Date 2017年8月25日 上午10:52:35
* @Version 1.0
* @Description 二叉查找树
*/
public class BinaryTree<T extends Comparable<T>> {
private Node<T> rootNode;
private ArrayList<T> dateList;
/**
* @ClassName Node类
* @Description 内部类 结点
* @param
*/
static class Node<T> {
T date;
Node<T> leftNode;
Node<T> rightNode;
public Node() {
}
public Node(T date) {
this.date = date;
}
@Override
public String toString() {
return date + " ";
}
}
public BinaryTree() {
}
public BinaryTree(T[] array) {
for (int i = 0; i < array.length; i++) {
insert(array[i]);
}
}
public BinaryTree(ArrayList<T> dateList) {
for (int i = 0; i < dateList.size(); i++) {
insert(dateList.get(i)); //随机访问
}
}
// 插入
public void insert(T date) {
Node<T> newNode = new Node<T>(date);
if (rootNode == null) {
rootNode = newNode;
} else {
Node<T> currentNode = rootNode;
while (true) {
if (date.compareTo(currentNode.date) == 0)
return;
if (date.compareTo(currentNode.date) < 0) {
Node<T> tempNode = currentNode.leftNode;
if (tempNode == null) {
currentNode.leftNode = newNode;
return;
}
currentNode = currentNode.leftNode;
} else {
Node<T> tempNode = currentNode.rightNode;
if (tempNode == null) {
currentNode.rightNode = newNode;
return;
}
currentNode = currentNode.rightNode;
}
}
}
}
// 查询与数据相同的节点并返回
private Node<T> findNode(T date) {
Node<T> currentNode = rootNode;
while (currentNode != null) {
if (date == currentNode.date)
return currentNode;
if (date.compareTo(currentNode.date) < 0) {
currentNode = currentNode.leftNode;
} else {
currentNode = currentNode.rightNode;
}
}
return null;
}
// 数据节点是否存在
public boolean isExist(T date) {
return findNode(date) == null ? false : true;
}
// 先序遍历递归实现
private void preOrder(Node<T> node, List<T> dateList) {
if (node != null) {
dateList.add(node.date);
preOrder(node.leftNode, dateList);
preOrder(node.rightNode, dateList);
}
}
public List<T> preOrder() {
dateList = new ArrayList<>();
if (rootNode == null) {
return dateList;
}
preOrder(rootNode, dateList);
return dateList;
}
// 先序遍历非递归实现
public List<T> preOrderOfStack() {
dateList = new ArrayList<T>();
if (rootNode == null) {
return dateList;
}
Stack<Node<T>> nodeStack = new Stack<Node<T>>();
nodeStack.push(rootNode);
while (!nodeStack.empty()) {
Node<T> topNode = nodeStack.pop();
dateList.add(topNode.date);
if (topNode.rightNode != null) {
nodeStack.push(topNode.rightNode);
}
if (topNode.leftNode != null) {
nodeStack.push(topNode.leftNode);
}
}
return dateList;
}
// 中序遍历递归实现
private void inOrder(Node<T> node, List<T> dateList) {
if (node != null) {
inOrder(node.leftNode, dateList);
dateList.add(node.date);
inOrder(node.rightNode, dateList);
}
}
public List<T> inOrder() {
dateList = new ArrayList<>();
if (rootNode == null) {
return dateList;
}
inOrder(rootNode, dateList);
return dateList;
}
// 中序遍历非递归实现
public List<T> inOrderOfStack() {
dateList = new ArrayList<T>();
if (rootNode == null) {
return dateList;
}
Stack<Node<T>> nodeStack = new Stack<Node<T>>();
Node<T> currentNode = rootNode;
while (currentNode != null || !nodeStack.empty()) {
while (currentNode != null) {
nodeStack.push(currentNode);
currentNode = currentNode.leftNode;
}
currentNode = nodeStack.pop();
dateList.add(currentNode.date);
currentNode = currentNode.rightNode;
}
return dateList;
}
// 后序遍历递归实现
private void postOrder(Node<T> node, ArrayList<T> dateList) {
if (node != null) {
postOrder(node.leftNode, dateList);
postOrder(node.rightNode, dateList);
dateList.add(node.date);
}
}
public List<T> postOrder() {
dateList = new ArrayList<>();
if (rootNode == null) {
return dateList;
}
postOrder(rootNode, dateList);
return dateList;
}
// 后序遍历非递归实现
public List<T> postOrderOfStack() {
dateList = new ArrayList<T>();
if (rootNode == null) {
return dateList;
}
Stack<Node<T>> nodeStack = new Stack<Node<T>>();
Node<T> currentNode = rootNode;
Node<T> lastUseRightNode = null; //记录最后访问的右节点,防止再次访问
while (currentNode != null || !nodeStack.empty()) {
while (currentNode != null) {
nodeStack.push(currentNode);
currentNode = currentNode.leftNode; //先访问左节点
}
currentNode = nodeStack.peek().rightNode; //再访问右节点
if (currentNode == null || currentNode == lastUseRightNode) { //防止死循环
currentNode = nodeStack.pop();
dateList.add(currentNode.date);
lastUseRightNode = currentNode;
currentNode = null;
}
}
return dateList;
}
}
欢迎批评指正!