二叉排序树

这篇博客详细介绍了二叉排序树的实现,包括添加、删除节点的方法。删除节点时考虑了三种情况:没有子节点、一个子节点和两个子节点。此外,还提供了中序遍历以确保关键码值按升序排列。

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

查询的效率高于链表。

排序规则举例:如1,2,3,5,7,如果有相同的数可以放在左子节点或右字节点上。

二叉排序树如果使用中序遍历肯定是关键码值由小到大递增的。

在删除某结点的时候,可以让左子节点替代自己。

实现方法,包括查找、删除、添加

public class SortNode {
	private int value;
	private SortNode left;
	private SortNode right;
	public SortNode(int value) {
		this.value=value;
	}
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public SortNode getLeft() {
		return left;
	}
	public void setLeft(SortNode left) {
		this.left = left;
	}
	public SortNode getRight() {
		return right;
	}
	public void setRight(SortNode right) {
		this.right = right;
	}
	@Override
	public String toString() {
		return "SortNode [value=" + value + "]";
	}
	//添加新的结点
	public void add(SortNode node) {
		if(node==null) {
			return;
		}
		/*
		 * 如果比它小,就往左放,如果比它大,就往右放。
		 */
		if(this.value>node.value) {
			if (this.left==null) {
				this.left=node;
			}else {
				this.left.add(node);
			}
		}
		if (this.value<=node.value) {
			if (this.right==null) {
				this.right=node;
			}else {
				this.right.add(node);
			}
		}
	}
	//遍历使用中序遍历,在顺序二叉树中,就会按照关键码值大小顺序排列。
	public void midList() {
		if (this.left!=null) {
			this.left.midList();
		}
		System.out.println(this);
		if (this.right!=null) {
			this.right.midList();
		}
	}
	//查询节点的方法,按照关键码值找。在顺序二叉树中,小于就往左边找,大于就往右边找
	public SortNode secNode(int value) {
		if (this.value==value) {
			return this;
		}else if(this.value<value) {
			if (this.left==null) {
				return null;
			}else {
				return this.left.secNode(value);
			}
		}else {
			if (this.right==null) {
				return null;
			}else {
				return this.right.secNode(value);
			}
		}
	}
	//查询节点的父节点,为删除准备
	public SortNode secFaNode(int value) {
		if (((this.left!=null)&&(this.left.value==value))||((this.right!=null)&&(this.right.value==value))) {
			return this;
		}else if((this.left!=null)&&(this.value<value)) {
			return this.left.secFaNode(value);
		}else if ((this.right!=null)&&(this.value>value)) {
			return this.right.secFaNode(value);
		}else {
			return null;
		}
	}
}

public class SortBinaryTree {
	private SortNode root;
	public SortBinaryTree(SortNode root) {
		this.root=root;
	}
	public SortNode getRoot() {
		return root;
	}
	
	//定义两个与结点方法相关的查找方法
	public SortNode secNode(int value) {
		if (root==null) {
			return null;
		}else {
			return root.secNode(value);
		}
	}
	public SortNode secFaNode(int Value) {
		if (root==null) {
			return null;
		}else{
			return root.secFaNode(Value);
		}
	}
	//遍历方法
	public void midList() {
		if(root==null) {
			return;
		}else {
			root.midList();
		}
	}
	//添加结点方法
	public void add(SortNode node) {
		if (root==null) {
			return;
		}else {
			root.add(node);
		}
	}
	//找到右子树最小值
	public SortNode findRightMin(SortNode node) {
		if(node.getRight()==null) {
			return node;
		}else {
			node=node.getRight();
			while(node.getLeft()!=null) {
				node=node.getLeft();
			}
			return node;
		}
	}
	/*
	 * 如果删除节点没有子节点,直接删除
	 * 如果有一个子树,直接让其替代自己
	 * 如果有两个子树,让左子树中最小的或右子树中最大的替代自己
	 */
	public void delNode(int value) {
		if (root==null) {
			return;
		}else {
			SortNode target=secNode(value);
			//因为root没有父节点,单独讨论
			if(root==target) {
				root=null;return;
			}
			if (target==null) {
				return;
			}else if((target.getRight()==null)&&(target.getLeft()==null)) {
				//要删除的结点没有子结点
				//现在判断要删除的结点是它父节点的左节点还是右结点
				SortNode faNode=secFaNode(value);
				if (faNode.getLeft()==target) {
					faNode.setLeft(null);
				}else {
					faNode.setRight(null);
				}
				//有一个结点的情况,分左右
			}else if((target.getLeft()!=null)&&target.getRight()==null) {
				SortNode faNode=secFaNode(value);
				if (faNode.getLeft()==target) {
					faNode.setLeft(target.getLeft());
				}else {
					faNode.setRight(target.getLeft());
				}
			}else if((target.getLeft()==null)&&target.getRight()!=null) {
				SortNode faNode=secFaNode(value);
				if (faNode.getLeft()==target) {
					faNode.setLeft(target.getRight());
				}else {
					faNode.setRight(target.getRight());
				}
			}else {
				//两个子树都有,找到右边最小的,把它放到被删结点位置上,再把它删了
				SortNode minRight=findRightMin(target);
				target.setValue(minRight.getValue());
				secFaNode(minRight.getValue()).setLeft(null);
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值