- 二叉搜索树要么是一颗空树,要么是满足以下条件的二叉树:对于二叉搜索树上每个节点X,左子树所有项的值小于X的值,右子树所有项的值大于X的值。
- 中序遍历二叉搜索树可以得到其升序排序结果。
- 以下代码提供了二叉搜索树创建、插入以及中序遍历的功能:
public class BinarySearchTree<T extends Comparable> {
private Node root;
public BinarySearchTree() {}
public BinarySearchTree(T[] array) {
for(T num : array) {
insert(new Node(num));
}
}
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
public void insert(Node node) {
if(root==null) {
root = node;
} else {
Node current = root;
Node parent = null;
while(true) {
parent = current;
if(node.getData().compareTo(current.getData())<0) { //往左
current = current.getLeft();
if(current==null) {
parent.setLeft(node);
break;
}
} else { //往右
current = current.getRight();
if(current==null) {
parent.setRight(node);
break;
}
}
}
}
}
//中序遍历
public void inOrderTraverse(Node root) {
if(root==null) {
return;
} else {
inOrderTraverse(root.getLeft());
System.out.print(root.getData()+"\t");
inOrderTraverse(root.getRight());
}
}
}
- 由于删除稍微有点麻烦,这里单独实现。思路如下:
- 如果是叶子节点,直接设为null即可(在代码里需要设置相应的父节点信息,否则父节点指向的位置没变,信息没有被真正删除);
- 如果仅有左孩子或右孩子,则直接用左孩子或右孩子替代该节点即可;
- 如果同时有左孩子和右孩子,根据中序遍历的性质,将右子树中最左侧节点替代该节点最佳(其实也可以找到左子树中最右侧的节点),然后递归删除那个最小节点。
具体实现代码如下:
public void remove(Node node) {
//首先要找到这个节点,并保存该节点的父节点信息
Node current = root;
Node parent = null;
while(true) {
parent = current;
if(node.getData().compareTo(current.getData())<0) { //在左子树中
current = current.getLeft();
if(current.getData().compareTo(node.getData())==0) { //找到该节点
break;
}
} else if(node.getData().compareTo(current.getData())==0){ //就是当前节点
break;
} else { //在右子树中
current = current.getRight();
if(current.getData().compareTo(node.getData())==0) { //找到该节点
break;
}
}
}
if(current.getLeft()==null&¤t.getRight()==null) { //叶子节点
if(current.getData().compareTo(parent.getLeft().getData())==0) {
parent.setLeft(null);
} else {
parent.setRight(null);
}
} else if(current.getLeft()!=null&¤t.getRight()==null) { //仅有左孩子
if(current.getData().compareTo(parent.getLeft().getData())==0) {
parent.setLeft(current.getLeft());
} else {
parent.setRight(current.getLeft());
}
} else if(current.getLeft()==null&¤t.getRight()!=null) { //仅有右孩子
if(current.getData().compareTo(parent.getLeft().getData())==0) {
parent.setLeft(current.getRight());
} else {
parent.setRight(current.getRight());
}
} else { //左右孩子都有
Node tmp = current.getRight();
parent = current;
while(tmp.getLeft()!=null) {
parent = tmp;
tmp = tmp.getLeft();
}
T min = (T)tmp.getData();
if(tmp.getData().compareTo(parent.getLeft().getData())==0) {
parent.setLeft(null);
} else {
parent.setRight(null);
}
current.setData(min);
}
}