下面的程序实现了一个二叉搜索树,每个结点的key为一个学生对象
二叉搜索树首先它是个二叉树,它的规则是一个结点的左子树的所有结点的值都比它小,右子树的所有结点的值都比它大。
要注意BST是要通过比较来进行很多操作的,如插入等,所以放入结点值的类型我们要实现比较。
BST类中实现的方法有:求树的高度,求树中最大最小值,中序遍历(有序),求某个结点的前驱与后继,插入结点。这些方法的时间复杂度大多是O(h)的(h一般为lgn最差为n),遍历为O(n)。
public class BSTMethodTest {
public static void main(String[] args) {
TreeNode lilei = new TreeNode(new Student(1001, "Lilei", "math"));
TreeNode hanmei = new TreeNode(new Student(1002, "Hanmei", "bio"));
TreeNode minnie = new TreeNode(new Student(1003, "Minnie", "math"));
TreeNode jerry = new TreeNode(new Student(1004, "Jerry", "bio"));
TreeNode mickey = new TreeNode(new Student(1005, "Mickey", "math"));
TreeNode tom = new TreeNode(new Student(1006, "Tom", "bio"));
BST bst = new BST(lilei);
bst.insert(hanmei);
bst.insert(minnie);
bst.insert(jerry);
bst.insert(mickey);
bst.insert(tom);
System.out.println("结点插入完后查看的中序遍历是:");
bst.inOrder(lilei);
System.out.print("寻找Mickey:");
TreeNode s = bst.search("Mickey");
System.out.println(s);
System.out.print("寻找Micke:");
TreeNode s1 = bst.search("Micke");
System.out.println(s1);
System.out.print("jerry的前驱是:");
System.out.println(bst.predecessor(jerry));
System.out.print("jerry的后继是:");
System.out.println(bst.successor(jerry));
}
}
class Student implements Comparable<Student>{//实现Comparable接口
private int id;
private String name;
private String profession;
public Student(int id,String name,String profession) {
this.id = id;
this.name = name;
this.profession = profession;
}
public String getName() {
return name;
}
public int compareTo(Student o) {//这里选择比较学生姓名来确定结点key的大小
return this.name.compareTo(o.name);
}
public int getId() {
return id;
}
public String getProfession() {
return profession;
}
}
class BST{//BST类
private TreeNode root;//BST的根结点
public BST(TreeNode root) {
this.root = root;
}
public void insert(TreeNode z) {
TreeNode cur = root;
TreeNode cur_p = null;//记录最后一次非null的cur,由于下面的迭代执行完cur必为null
while(cur != null) {//直到当前节点的某个子节点无的时候
cur_p = cur;//保留不为null的当前点
if(z.key.compareTo(cur.key) < 0) {
cur = cur.left;
}else cur = cur.right;
}
if(cur_p == null)//此树为空
root = z;
else if(z.key.compareTo(cur_p.key) < 0) {
cur_p.left = z;
z.parent = cur_p;
}
else {
cur_p.right = z;
z.parent = cur_p;
}
}
public TreeNode search(String name) {
TreeNode cur = root;
while(cur != null && !name.equals(cur.key.getName())) {
if(name.compareTo(cur.key.getName()) < 0) {
cur = cur.left;
}else cur = cur.right;
}
return cur;
}
public TreeNode tree_Minimum(TreeNode root) {
if(root == null || root.left == null)
return root;
return tree_Minimum(root.left);
}
public TreeNode tree_Maximum(TreeNode root) {
while(root != null && root.right != null)
root = root.right;
return root;
}
public void inOrder(TreeNode root) {
if(root == null)
return;
inOrder(root.left);
System.out.println(root.key.getName());
inOrder(root.right);
}
public TreeNode successor(TreeNode x) {//默认输入不是null
if(x.right != null) {
return tree_Minimum(x.right);
}
TreeNode y = x.parent;
while(y != null && x == y.right) {//必须满足有父节点且自身是父节点的右结点,是左节点即是后继
x = y;
y = x.parent;
}
return y;
}
public TreeNode predecessor(TreeNode x) {//默认输入不是null
if(x.left != null) {
return tree_Maximum(x.left);
}
TreeNode y = x.parent;
while(y != null && x == y.left) {
x = y;
y = x.parent;
}
return y;
}
public int treeHeight(TreeNode root){
if(root == null)
return 0;//相当于最下面一层的左或右结点,显然为null,不能返回1,因为他们不是存在的结点。
return Math.max(treeHeight(root.left) + 1, treeHeight(root.right) + 1);//要注意每次递归返回后加1。代表从下往上层数增加
}
}
class TreeNode{//结点类
Student key;//结点值
TreeNode left;//结点的左结点
TreeNode right;//右结点
TreeNode parent;//父结点
public TreeNode(Student key) {
this.key = key;
left = right = parent = null;
}
public String toString() {
return "找到的是" + key.getName() + "";
}
}