二叉排序树

二叉排序树:或者是一棵空树;或者是具有下列性质的二叉树:
(1)若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
(2)若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
(3)它的左、右子树也分别为二叉排序树

import java.util.Scanner;
 
/**
 * 二叉排序树 (binary sort tree)
 * 对于一个根节点,其左子树上所有节点的值都小于根节点的值
 * 而右子树节点上的权值都大于根节点的权值
 * @author tiny_spot
 */
public class BSTree {
	static Scanner s = new Scanner(System.in);
	public static int END_FLAG = 0x7fffffff;
	public static void main(String []args) {
		//System.out.println("结尾标志符:"+END_FLAG);
		System.out.println("按ctrl+z结束输入....");
		BSTNode root = createBST();
		if(root == null)
			System.out.println("二叉排序树为空!");
		else {
			inOrder(root);//中序输出 
			System.out.println();
			//preOrder(root);
			root = deleteBST(root, 17);
			inOrder(root);
			System.out.println();
			root = deleteBST(root, 78);
			inOrder(root);
		}
		s.close();
	}
	/**
	 * 创建二叉排序树
	 * @return 二叉树的根节点
	 */
	public static BSTNode createBST() {
		int t;
		BSTNode root = new BSTNode();
		if(s.hasNext()) {
			t = s.nextInt();
			root.val = t;
			while(s.hasNext()) {
				t = s.nextInt();
				insertBST(root, t);
			}
		}else return null;
		return root;
	}
	/**
	 * 将节点插入二叉排序树
	 * @param root 二叉树的根节点
	 * @param n	待插入的值
	 */
	public static void insertBST(BSTNode root ,int n) {
		if(root == null) {//如果为真,表明这是整棵树的根节点
			root.val = n;
			return ;
		}
		if(root.val > n) {
			if(root.left == null) {
				root.left = new BSTNode();
				root.left.val = n;
				return;
			}
			insertBST(root.left, n);
		}else{//如果根节点的值小于等于n,则把n放到右子树上
			if(root.right == null) {
				root.right = new BSTNode();
				root.right.val = n;
				return;
			}
			insertBST(root.right, n);
		}
	}
	/**
	 * 删除节点值为key的节点,并保持二叉树原有的特性
	 * 如果不存在节点值为key的节点,则什么都不做
	 * @param root	二叉树的根节点
	 * @param key	待删除的 值
	 * @return 返回树的根节点
	 */
	public static BSTNode deleteBST(BSTNode root ,int key) {
		BSTNode p = root, q, f=null;
		while(p != null) {//查找节点值为key的节点
			if(p.val == key)
				break;
			f = p;
			if(p.val > key)
				p = p.left;
			else p = p.right;
		}
		if(p == null)//表明树中没有key这个关键字
			return root;
		q = p;   	//此时p和q都是目标节点的引用
		if(p.left!=null && p.right!=null) {//若被删节点左右子树均不为空 ,则删除该节点左子树中最右端节点,并将其值赋给p
			BSTNode s = p.left;
			while(s.right != null){//一直往左子树的右边找
				q = s;//q为s的上一个节点
				s = s.right;
			}//出循环之后,s节点是没有右子树的!
			p.val = s.val;//改变待删节点的值即表示删除它
			if(p == q)//表示s节点为待删节点的左子树的根节点,此时s节点的父亲节点为p或q,这时s节点是否有左子树未知,所以将s的左子树重接至p的左子树
				q.left = s.left;
			else q.right = s.left;//p!=q 表示待删节点的左子树还有右孩子节点,此时s节点的父亲节点为q,所以需要用s的左子树重接q的右子树
			s = null;//删除s节点
		}else if(p.left != null) {//待删节点只有左子树,右子树为空
			q = p.left;
			p.val = q.val;
			p.left = q.left;
			p.right = q.right;
			q = null;
		}else if(p.right != null) {//待删节点只有右子树,左子树为空
			q = p.right;
			p.val = q.val;
			p.left = q.left;
			p.right = q.right;
			q = null;
		}else {//待删节点是叶子节点
			if(f == null) { //f=null表明待删节点是树的分界点,并且这棵树没有左右子树
				return null;
			}else {
				if(f.left.val == key)
					f.left = null;
				else f.right = null;
			}
		}
		return root;
	}
	/**
	 * 中序遍历,其结果就是一个完整的排好序的序列
	 * @param root 二叉树的根节点
	 */
	public static void inOrder(BSTNode root) {
		if(root == null)
			return;
		inOrder(root.left);
		System.out.print(root.val + " ");
		inOrder(root.right);
	}
	/**
	 * 前序遍历
	 * @param root 二叉树的根节点
	 */
	public static void preOrder(BSTNode root) {
		if(root == null)
			return ;
		System.out.print(root.val + " ");
		preOrder(root.left);
		preOrder(root.right);
	}
}
class BSTNode{
	BSTNode left=null;
	BSTNode right = null;
	public int val;
}
// 45 24 53 12 37 93 2147483647
// 12 24 37 45 53 93 2147483647
// 46 24 12 53 -10 12 37 45 93 2147483647
// 53 17 78 9 65 45 87 23 87
// 5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值