二叉搜索树(Java)

下面的程序实现了一个二叉搜索树,每个结点的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() + "";
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值