二叉排序树(Java)

二叉排序树(Java)

二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。

定义

一棵空树,或者是具有下列性质的二叉树称为二叉排序树:

  • 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 左、右子树也分别为二叉排序树;
相关操作
举个栗子

以结点权值集合为arr= {3,1,8,9,6,4,7}为例

1.添加结点
  • 如果插入结点小于当前结点,则放在左子树
  • 如果插入结点大于当前结点,则放在右子树
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
代码如下
public void add(Node no) {//添加结点
		if(no==null) {
			return;
		}
		if(no.data!=this.data) {
		if(no.data<this.data) {//如果插入结点小于当前结点,则放在左子树
			if(this.left==null) {
				this.left=no;
			}else {//递归向左子树递归
				this.left.add(no);
			}
		}
		if(no.data>this.data) {//如果插入结点大于当前结点,则放在右子树
			if(this.right==null) {
				this.right=no;
			}else {//递归向右子树递归
				this.right.add(no);
			}
		}	
		}	
	}
2.查找元素
public void  search(int data) {//查找结点
		if(data==this.data) {
			System.out.printf("查询到%d结点",data);
		}else if(data<this.data) {//查找元素小于当前元素,则向左子树递归
			if(this.left==null) {
				System.out.println("二叉排序树中没有该结点!");
			}
			 this.left.search(data);
		}else {//查找元素大于当前结点元素,则向右子树递归
			if(this.right==null) {
				System.out.println("二叉排序树中没有该结点!");
			}
			 this.right.search(data);
		}
	}
3.删除结点

主要分为四种情况:

  • 如果删除结点是叶子节点
  • 如果删除结点只有右子树
  • 如果删除结点只有左子树
  • 如果删除结点为父结点

以删除父结点8为例:
删除结点同时要保持排序二叉树的性质,所以我们可以让左子树中最大或者右子树中最小的结点替换当前节点,同时将置换结点置空
在这里插入图片描述

代码如下
public Node delete(Node root, int key) {//删除结点
		if (root == null)
		{
			return null;
		}
		if (key < root.getData()){// 向左子树进行删除
			root.setLeft(delete(root.getLeft(), key));
			return root;
		}
		if (key > root.getData()){// 向右子树进行删除
			root.setRight(delete(root.getRight(), key));
			return root;
		}
		if (root.getLeft() == null && root.getRight() == null){// 如果删除结点是叶子节点
			root = null;
			return root;
		}
		if (root.getLeft() == null && root.getRight() != null){// 如果删除结点只有右子树
			root = root.getRight();
			return root;
		}
		if (root.getRight() == null && root.getLeft() != null){// 如果删除结点只有左子树
			root = root.getLeft();
			return root;
		}
		if (root.getLeft() != null && root.getRight() != null){// 如果删除结点为父结点
			int val = findMaxInLeftTree(root.getLeft());// 让左子树中最大或者右子树中最小的结点替换当前节点,同时将置换结点置空
			root.setData(val);
			root.setLeft(delete(root.getLeft(),val));
			return root;
		}
		return root;
	}
完整代码

public class Binarysorttree2 {

	public static void main(String[] args) {
		int arr[]= {3,1,8,9,6,4,7};
		binarysorttree binary=new binarysorttree();
		for(int i=0;i<arr.length;i++) {//创建二叉排序树
			binary.add(new Node(arr[i]));
		}
		System.out.println("----创建二叉排序树完成----");
		System.out.println("前序遍历结果为:");
		binary.preorder();
		System.out.println("中序排序结果为:");
		binary.infixorder();
		binary.deleteNode(8);
		System.out.println("----删除结点后二叉排序排序树----");
		System.out.println("前序遍历结果为:");
		binary.preorder();
		System.out.println("中序排序结果为:");
		binary.infixorder();
		System.out.println("----查询结点----");
		binary.search(9);
	}

}
class binarysorttree{
	private Node root;
	public void add(Node no) {//添加结点
		if(root==null) {
			root=no;
		}else {
			root.add(no);
		}
	}
	public void deleteNode(int data) {//删除结点
		if(root==null) {
			System.out.println("二叉排序树为空,无法删除结点!");
		}else {
			root.delete(root, data);
		}			
	}
	public void search(int data) {
		root.search(data);
		
	}
	//前序遍历
	public void preorder() {
		if(root==null) {
			System.out.println("二叉排序树为空!");
		}else {
			root.preorder();
		}
		System.out.println();
	}
	//中序遍历
	public void infixorder() {
		if(root==null) {
			System.out.println("二叉树为空!");
		}else {
			root.infixorder();
		}
		System.out.println();
	}
	
		

		
}
class Node{
	int data;
	int flag;
	Node left;
	Node right;
	public Node(int data) {
		this.data=data;
	}
	
	public int getData() {
		return data;
	}

	public void setData(int data) {
		this.data = data;
	}

	public Node getLeft() {
		return left;
	}

	public void setLeft(Node left) {
		this.left = left;
	}

	public Node getRight() {
		return right;
	}

	public void setRight(Node right) {
		this.right = right;
	}
	
	
	public int hashCode() {
		return right.hashCode();
	}

	public boolean equals(Object obj) {
		return right.equals(obj);
	}

	@Override
	public String toString() {
		return  data + " ";
	}
	//前序遍历
		public void preorder() {
			System.out.print(this);
			if(this.left!=null) {
				this.left.preorder();
			}
			if(this.right!=null) {
				this.right.preorder();
			}
			
		}
		//中序遍历
		public void infixorder() {
			if(this.left!=null) {
				this.left.infixorder();
			}
			System.out.print(this);
			if(this.right!=null) {
				this.right.infixorder();
			}
			
		}
		
	public void add(Node no) {//添加结点
		if(no==null) {
			return;
		}
		if(no.data!=this.data) {
		if(no.data<this.data) {//如果插入结点小于当前结点,则放在左子树
			if(this.left==null) {
				this.left=no;
			}else {//递归向左子树递归
				this.left.add(no);
			}
		}
		if(no.data>this.data) {//如果插入结点大于当前结点,则放在右子树
			if(this.right==null) {
				this.right=no;
			}else {//递归向右子树递归
				this.right.add(no);
			}
		}	
		}	
	}
	public void  search(int data) {//查找结点
		if(data==this.data) {
			System.out.printf("查询到%d结点",data);
		}else if(data<this.data) {//查找元素小于当前元素,则向左子树递归
			if(this.left==null) {
				System.out.println("二叉排序树中没有该结点!");
			}
			 this.left.search(data);
		}else {//查找元素大于当前结点元素,则向右子树递归
			if(this.right==null) {
				System.out.println("二叉排序树中没有该结点!");
			}
			 this.right.search(data);
		}
	}
	public Node delete(Node root, int key) {//删除结点
		if (root == null)
		{
			return null;
		}
		if (key < root.getData()){// 向左子树进行删除
			root.setLeft(delete(root.getLeft(), key));
			return root;
		}
		if (key > root.getData()){// 向右子树进行删除
			root.setRight(delete(root.getRight(), key));
			return root;
		}
		if (root.getLeft() == null && root.getRight() == null){// 如果删除结点是叶子节点
			root = null;
			return root;
		}
		if (root.getLeft() == null && root.getRight() != null){// 如果删除结点只有右子树
			root = root.getRight();
			return root;
		}
		if (root.getRight() == null && root.getLeft() != null){// 如果删除结点只有左子树
			root = root.getLeft();
			return root;
		}
		if (root.getLeft() != null && root.getRight() != null){// 如果删除结点为父结点
			int val = findMaxInLeftTree(root.getLeft());// 让左子树中最大或者右子树中最小的结点替换当前节点,同时将置换结点置空
			root.setData(val);
			root.setLeft(delete(root.getLeft(),val));
			return root;
		}
		return root;
	}
			private static int findMaxInLeftTree(Node left) {// 找到左子树中最大的节点的值
				if (left == null)
				{
					return 0;
				}
				if (left.getRight() == null)
				{
					return left.getData();
				}
				if (left.getRight() == null && left.getLeft() == null)
				{
					return left.getData();
				}
				return findMaxInLeftTree(left.getRight());
			}
	
	
}
运行结果
----创建二叉排序树完成----
前序遍历结果为:
3 1 8 6 4 7 9 
中序排序结果为:
1 3 4 6 7 8 9 
----删除结点后二叉排序排序树----
前序遍历结果为:
3 1 7 6 4 9 
中序排序结果为:
1 3 4 6 7 9 
----查询结点----
查询到9结点
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉排序树(Binary Search Tree,BST)是一种特殊的二叉树,它满足以下条件: - 左子树中的所有节点的值均小于根节点的值; - 右子树中的所有节点的值均大于根节点的值; - 左右子树也分别为二叉排序树Java代码实现二叉排序树: ```java class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class BinarySearchTree { private TreeNode root; // 根节点 // 插入节点 public void insert(int val) { if (root == null) { // 如果根节点为空,直接插入 root = new TreeNode(val); return; } TreeNode cur = root; while (cur != null) { if (val < cur.val) { // 小于当前节点,往左子树找 if (cur.left == null) { cur.left = new TreeNode(val); return; } cur = cur.left; } else { // 大于等于当前节点,往右子树找 if (cur.right == null) { cur.right = new TreeNode(val); return; } cur = cur.right; } } } // 查找节点 public boolean search(int val) { TreeNode cur = root; while (cur != null) { if (val == cur.val) { return true; } else if (val < cur.val) { cur = cur.left; } else { cur = cur.right; } } return false; } // 删除节点 public void delete(int val) { root = deleteNode(root, val); } private TreeNode deleteNode(TreeNode root, int val) { if (root == null) { // 没有找到要删除的节点 return null; } if (val < root.val) { // 继续在左子树中删除 root.left = deleteNode(root.left, val); } else if (val > root.val) { // 继续在右子树中删除 root.right = deleteNode(root.right, val); } else { // 找到要删除的节点 if (root.left == null) { // 左子树为空或者左右子树都为空 return root.right; } else if (root.right == null) { // 右子树为空 return root.left; } else { // 左右子树都不为空 TreeNode minNode = findMin(root.right); // 找到右子树中最小的节点 root.val = minNode.val; // 用右子树中最小的节点代替要删除的节点 root.right = deleteNode(root.right, minNode.val); // 删除右子树中最小的节点 } } return root; } // 找到以root为根的二叉搜索树的最小节点 private TreeNode findMin(TreeNode root) { while (root.left != null) { root = root.left; } return root; } } ``` 以上代码实现了二叉排序树的基本操作:插入节点、查找节点和删除节点。其中删除节点需要考虑三种情况:左子树为空、右子树为空和左右子树都不为空。对于第三种情况,需要在右子树中找到最小的节点代替要删除的节点,然后再删除右子树中最小的节点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值