二叉搜索树

排序二叉树的性质:

  1. 如果左子树不为空,则左子树上的点都小于根节点。

  2. 如果右子树不为空,则右子树上的点都大于根节点。

  3. 根节点的左子树和右子树都是二叉排序树

排序二叉树的添加操作

  1. 从根节点开始,作为当前节点

  2. 那当前节点与插入节点的值进行比较

  3. 若比当前节点大,把当前节点的右子节点作为当前结点,比当前节点的小,将左节点作为当前节点进行比较

  4. 重复2,3步骤直到找到合适的叶子结点

  5. 若比叶子节点大,就插到叶子结点的右子节点,反之插到左子节点

排序二叉树的删除操作的情况有下面四种

  1. 无子节点,直接删除

  2. 只有左子树或左节点,将删除节点的左节点作为根节点即可

  3. 只有右子树或右节点,将删除节点的右子节点作为根节点

  4. 即有右子树,又有左子树,这种情况为了方便自己记忆,我是只采取一种方法,就是采取该删除节点的前驱节点或后继节,来补删除节点的位置。(前驱节点就是比删除节点所有小的节点中里面最大的值,后继节点就是比删除节点都大的节点中的最小点)(2 7 8 10 15 17)例如删除节点是10,则前驱就是8,后继就是15

    185007_6k6M_255939.jpg185017_1HSv_255939.jpg

如图片上的,删除20这个点,可以用前驱15或后继30来作为补位的节点

public class BinarySortTree {
	public static class Node {
		private int data;
		private String name;
		private Node leftNode;
		private Node rightNode;
		private Node parent;

		public Node(int data, Node parentNode) {
			super();
			this.data = data;
			this.parent = this.parent;
		}

		public Node(int data, String name) {
			super();
			this.data = data;
			this.name = name;
		}
		public Node(int data) {
			super();
			this.data = data;
		}
		public Node() {
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getData() {
			return data;
		}
		public void setData(int data) {
			this.data = data;
		}

		public Node getLeftNode() {
			return leftNode;
		}

		public void setLeftNode(Node leftNode) {
			this.leftNode = leftNode;
		}

		public Node getRightNode() {
			return rightNode;
		}

		public void setRightNode(Node rightNode) {
			this.rightNode = rightNode;
		}

		public Node getParent() {
			return parent;
		}

		public void setParent(Node parent) {
			this.parent = parent;
		}
	}
	
	private Node root;
	
	public Node addNode(Node node){
		if(root==null){
			root=node;
		}else{
			Node parent=getNodeIndex(root, node.getData());
			node.parent=parent;
			if(parent.getData()>node.getData()){
				parent.leftNode=node;
			}else{
				parent.rightNode=node;
			}
		}
		
		return root;
	}
	
	private Node getNodeIndex(Node node,int data){
		if(data>=node.getData()){
			if(node.getRightNode()==null){
				return node;
			}else{
				return getNodeIndex(node.rightNode, data);
			}
		}else {
			if(node.getLeftNode()==null){
				return node;
			}else{
				return getNodeIndex(node.leftNode, data);
			}
		}
	}
	//广度遍历
	public void breadth(){
		Queue<Node> queue=new ArrayDeque<>();
		if(root!=null){
			queue.add(root);
			while(!queue.isEmpty()){
				Node node=queue.poll();
				if(node.leftNode!=null)
					queue.add(node.leftNode);
				if(node.rightNode!=null)
					queue.add(node.rightNode);
				System.out.print(node.getData()+"-");
			}
		}
	}
	//中序遍历
	public void middle(){
		if(root!=null){
			pMiddle(root);
		}
	}
	private void pMiddle(Node node){
		if(node!=null){
			if(node.leftNode!=null)
			{
				pMiddle(node.leftNode);
			}
			System.out.println(node.getData());
			if(node.rightNode!=null){
				pMiddle(node.rightNode);
			}
		}
	}
	
	public void delete(int data){
		if(root!=null){
			Node node=search(root, data);
			if(node.leftNode==null&node.rightNode==null){
				Node parentNode=node.parent;
				if(parentNode.leftNode.getData()==data){
					parentNode.leftNode=null;
				}else {
					parentNode.rightNode=null;
				}
			}
			if(node.leftNode==null){
				Node parentNode=node.parent;
				if(parentNode.leftNode.getData()==data){
					parentNode.leftNode=node.rightNode;
				}else {
					parentNode.rightNode=node.rightNode;
				}
			}
			if(node.rightNode==null){
				Node parenNode=node.parent;
				if(parenNode.leftNode.getData()==data){
					parenNode.leftNode=node.leftNode;
				}else{
					parenNode.rightNode=node.leftNode;
				}
			}
			//既有右子树,又有做子树
			if(node.rightNode!=null&node.leftNode!=null){
				Node preNode=findPreNode(node);
				Node preParentNode=preNode.parent;
				if(preParentNode.leftNode.getData()==preNode.getData()){
					preParentNode.leftNode=null;
				}else{
					preParentNode.rightNode=null;
				}
				preNode.rightNode=node.rightNode;
				node.rightNode.parent=preNode;
				preNode.leftNode=node.leftNode;
				node.leftNode.parent=preNode;
				Node parentNode=node.parent;
				parentNode.rightNode=preNode;
			}
		}
	}
	/**
	 * 查找某个点的前驱节点
	 * @param node
	 * @return
	 */
	private Node findPreNode(Node node){
		Node rightSonNode=node.leftNode;
		while(rightSonNode.rightNode!=null){
			rightSonNode=rightSonNode.rightNode;
		}
		return rightSonNode;
	}
	/**
	 * 从根节点开始查找节点
	 * @param node
	 * @param data
	 * @return
	 */
	public Node search(Node node,int data){
		
		if(data==node.getData())
			return node;
		if(data>node.getData()){
			if(node.rightNode!=null){
				return search(node.rightNode, data);
			}else{
				return null;
			}
				
		}else{
			if(node.leftNode!=null){
				return search(node.leftNode, data);
			}else{
				return null;
			}
		}
	}
	public static void main(String[] args) {
		BinarySortTree tree=new BinarySortTree();
		tree.addNode(new Node(5));
		tree.addNode(new Node(20));
		tree.addNode(new Node(10));
		tree.addNode(new Node(3));
		tree.addNode(new Node(8));
		tree.addNode(new Node(15));
		tree.addNode(new Node(30));
		tree.middle();
		tree.delete(20);
		tree.middle();
	}
}

190248_Zi9o_255939.jpg

转载于:https://my.oschina.net/u/255939/blog/637941

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值