二叉排序树Java实现(Binary Sort Tree)

本文详细介绍了二叉排序树的基本概念、创建、插入、查询、删除等操作,并提供了Java实现代码示例。深入理解二叉排序树的特性及其实现方式,有助于掌握高效的数据结构和算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉排序树又称二叉查找树,它是一种对排序查找都很有用的特殊二叉树。

二叉树的定义:二叉树或者是一颗空树,或者是具有下列性质的二叉树:

1.若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;

2.若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;

3.它的左右子树也分别为二叉排序树。

简单的说就是(左 <  根 < 右)

二叉排序树的创建:从空的二叉排序树开始,每输入一个结点,经过查找操作,将新结点插入到当前二叉排序树的合适位置。

二叉排序树的插入:对于待插入的结点,根据二叉排序树的特性找到该结点合适的位置并插入。

二叉排序树的查询:对于带查询的结点,根据二叉排序树的特性从树根一直往下找,直到找到为止或者未找到。

二叉排序树的删除:

1.从树根开始查找待删结点,若树中不存在该结点,则不做任何操作。

2.若找到待删结点,设待删结点为d,则分3种情况考虑---d的左右子树均不空,d无左子树,d无右子树

   a.左右子树均不空:在d的左子树中,找到最右边的结点p,然后将该节点放入d所在位置(相当于用p取代d,仔细想想就会发   现只有这个结点放入d,才会使整颗二叉排序树保持原有特性)

   b.无右子树:只需将左子树接上去即可。

   c.无左子树,只需将右子树接上去即可。

二叉排序树的中序遍历就是整个待排序序列的最终结果。

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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值