二叉查找树是一种特殊的二叉树。其中每个结点都包含一个索引,每个结点的索引都大于其左子树中任意结点的索引,小于其右子树中任意结点的索引。
对象BST代表一棵二叉查找树,其中root变量是二叉查找树的根节点。
之后分别实现增删改查的操作,以及查找第几结点和查询某结点是第几结点。
import java.util.Stack;
public class BST {
private Node root;
public Node getRoot() {
return this.root;
}
public void setRoot(Node root) {
this.root = root;
}
//根据val值在root二叉查找树找到相应的node结点并返回,如果没有则返回null
public Node get(Comparable index) {
return get(index, this.root);
}
public Node get(Comparable index, Node root) {
if(root == null)
return null;
int cmp = root.getIndex().compareTo(index);
if(cmp > 0)
return get(index, root.getLeft());
if(cmp < 0)
return get(index, root.getRight());
return root;
}
//在root二叉查找树中插入结点x,如果出现索引相同,则进行替换。
public void put(Node x) {
root = put(x, this.root);
}
public Node put(Node x, Node root) {
if(root == null) {
return new Node(x);
}
int cmp = root.getIndex().compareTo(x.getIndex());
if(cmp > 0)
root.setLeft(put(x, root.getLeft()));
else if(cmp < 0)
root.setRight(put(x, root.getRight()));
else
root.setInformation(x.getInformation());
return root;
}
//找到root二叉查找树的最大结点并返回
public Node max() {
return max(this.root);
}
public Node max(Node root) {
if(root == null)
return null;
if(root.getRight() == null)
return root;
else
return max(root.getRight());
}
//找到root二叉查找树的最小结点并返回
public Node min() {
return min(this.root);
}
public Node min(Node root) {
if(root == null)
return null;
if(root.getLeft() == null)
return root;
else
return min(root.getLeft());
}
//输入结点x,返回他的排名, 最小的为0,然后依次递增
public int rank(Node x) {
return rank(x, this.root);
}
private int rank(Node x, Node root) {
if(root == null)
return 0;
int cmp = root.getIndex().compareTo(x.getIndex());
return rank(x, root.getLeft()) + (cmp < 0?1:0) + rank(x, root.getRight());
}
//输入排名, 最小的为0,然后依次递增,返回其结点
public Node select(int rank) {
return select(rank, this.root);
}
private Node select(int rank, Node root) {
Stack<Node> stack = new Stack<>();
int tRank = -1;
while(root != null || !stack.isEmpty()) {
while(root != null) {
stack.push(root);
root = root.getLeft();
}
if(!stack.isEmpty()) {
root = stack.pop();
if((++tRank) == rank)
return root;
root = root.getRight();
}
}
return null;
}
//删除二叉查找树最小的结点
private Node deleteMin(Node root) {
if(root == null)
return null;
if(root.getLeft() == null)
return root.getRight();
root.setLeft(deleteMin(root.getLeft()));
return root;
}
//输入索引,删除二叉查找树的该索引的结点
public void delete(Comparable index) {
this.root = delete(this.root, index);
}
private Node delete(Node root, Comparable index) {
if(root == null)
return null;
int cmp = root.getIndex().compareTo(index);
if(cmp > 0) {
root.setLeft(delete(root.getLeft(), index));
}else if(cmp < 0) {
root.setRight(delete(root.getRight(), index));
}else {
if(root.getLeft() == null)
return root.getRight();
if(root.getRight() == null)
return root.getLeft();
Node t = root;
root = min(t.getRight());
root.setRight(deleteMin(t.getRight()));
root.setLeft(t.getLeft());
}
return root;
}
public static void main(String[] args) {
BST bst = new BST();
bst.put(new Node(Integer.valueOf(20), "20i"));
bst.put(new Node(Integer.valueOf(10), "10i"));
bst.put(new Node(Integer.valueOf(30), "30i"));
bst.put(new Node(Integer.valueOf(1), "1i"));
bst.put(new Node(Integer.valueOf(14), "14i"));
bst.put(new Node(Integer.valueOf(25), "25i"));
bst.put(new Node(Integer.valueOf(34), "34i"));
System.out.println("最大的结点索引值为:"+bst.max(bst.getRoot()).getIndex());
System.out.println("最小的结点索引值为:"+bst.min().getIndex());
System.out.println("结点25的排名:"+bst.rank(new Node(Integer.valueOf(25), "25i")));
System.out.println("排名为4的结点索引为:"+bst.select(4).getIndex());
bst.delete(Integer.valueOf(10));
System.out.println("删除索引为10的结点后,排名为1的索引为"+bst.select(1).getIndex());
}
}
class Node {
private Comparable index;
private String information;
private Node left, right;
public Node(Comparable index, String information) {
this.index = index;
this.information = information;
}
public Node(Node x) {
this.index = x.getIndex();
this.information = x.getInformation();
}
public Comparable getIndex() {
return index;
}
public String getInformation() {
return information;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public Node(int index) {
this.index = index;
}
public void setIndex(Comparable index) {
this.index = index;
}
public void setInformation(String information) {
this.information = information;
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
}