二分搜索树(自用)

本文深入探讨了二分搜索树的实现原理,包括节点结构、插入、查找、遍历(前序、中序、后序)、获取最大最小值、删除节点等核心操作,并附带了详细的代码示例。

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

二分搜索树

今天七夕,然后我再公司宿舍写代码!!!好吧~我承认我酸了,不想进行讲解,我就是将今天的事记录下,而且也不知道咋回事,回来倒头就睡,可能是算法太耗费脑子了吧,也不知道是因为算法还是情人节闹的~反正就是特么蔫吧了一整天,现在的时间是2019年8月7日23:09:19,代码你们粘过去也运行不了,因为里面用到了我自己写的队列Queue


package com.myTree;

import com.xsh.April_Month23Day_Queue.CommonQueue;
import com.xsh.April_Month23Day_Queue.Queue;

/**
 * 
 * @author lenovo
 * 
 * 二分搜索树
 *
 */
public class BST<E extends Comparable> {
		
	// Node 节点
	private class Node<E extends Comparable>{
		
		// 节点的值
		private E value;
		// 左子节点
		private Node left;
		// 右子节点
		private Node right;

		public Node(E value) {
			this.value = value;
			
			this.left = null;
			this.right = null;
		}

		public E getValue() {
			return value;
		}

		public void setValue(E value) {
			this.value = value;
		}

		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;
		}
		
	}
	// 根节点
	private Node root;
	// 节点的个数
	private int size;
	// 默认构造函数
	public BST() {

		this.root = null;
		this.size = 0;
	}
	// 添加构造节点  ---> 对外暴露方法
	public void add(E value) {
		
		// 进一步深化 迭代算法
		if (root == null) {
			root = new Node(value);
			return;
		}
		add(root,value);
	}
	// 内部实际实现算法
	private void add(Node node,E value) {
		
		// 递归终止条件
		if (value.compareTo(node.value) < 0 && node.left == null) {
			size++;
			node.left = new Node(value);
		} else if(value.compareTo(node.value) > 0 && node.right == null) {
			size++;
			node.right = new Node(value);
		}
		// 递归条件
		if (value.compareTo(node.value) < 0) {
			add(node.left,value);
		} else if(value.compareTo(node.value) > 0) {
			add(node.right,value);
		}
	}
	// 判断特定节点的值是否存在 --- 对外暴露方法
	public boolean isExist(E value) {
		
		if (root == null) return false;
		
		return isExist(root,value);
	}
	// 内部真正实现的方法
	private boolean isExist(Node node,E value) {
		
		if (value.compareTo(node.value) == 0) {
			return true;
		} else if (value.compareTo(node.value) < 0 && node.left == null) {
			return false;
		} else if(value.compareTo(node.value) > 0 && node.right == null) {
			return false;
		}
		
		if (value.compareTo(node.value) < 0) {
			return isExist(node.left,value);
		} else{ //(value.compareTo(node.value) > 0)
			return isExist(node.right,value);
		}
	}
	// 前序遍历 --- 又称根序遍历 --- 根左右
	public void preOrder() {
		if (root == null) throw new IllegalArgumentException("二分搜索树为NULL");
		preOrder(root);
	}
	// 内部真正实现 -- 前序遍历
	private void preOrder(Node root) {
		
	    if (root == null)
	        return;
	    
		System.out.println(root.value);
		preOrder(root.left);
		preOrder(root.right);
		
	}
	// 后序遍历 --- 又称后根遍历 --- 左右根 --- 对外暴露实现的方法
	public void afterOrder() {
		if (root == null) throw new IllegalArgumentException("当前二分搜索树为NULL");
		afterOrder(root);
	}
	// 内部真正实现 -- 后序遍历
	private void afterOrder(Node node) {

		if (node == null) return;

		afterOrder(node.left);
		afterOrder(node.right);
		System.out.println(node.value);



	}
	// 中序遍历 --- 又叫做中根遍历 --- 左根右 --- 对外暴露实现的方法
	public void midOrder() {
		if (root == null) throw new IllegalArgumentException("二叉树为NULL");
		midOrder(root);
	}
	// 内部真正实现 -- 中序遍历
	private void midOrder(Node node) {

		if (node == null) return;

		midOrder(node.left);
		System.out.println(node.value);
		midOrder(node.right);
	}
	// 查找该二叉树的最小值 -- 对外暴露的方法
	public E min() {
		if (root == null) throw new IllegalArgumentException("当前二叉树为NULL");
		Node node = min(root);
		return (E) node.value;
	}
    // 内部真正实现 -- 查找二叉树的最小值
	private Node min(Node node) {

		if (node.left == null)
			return node;

		return min(node.left);
	}
	// 查找二叉树的最大值 -- 对外暴露的方法
	public E max() {
		if (root == null) throw new IllegalArgumentException("当前二叉树为NULL");
		Node node = max(root);
		return (E) node.value;
	}
	// 内部真正实现 -- 查找二叉树的最大值
	private Node max(Node node) {
		if(node.right == null) return node;

		return max(node.right);
	}
	// 层序遍历 -- 一层一层来,这个跟前面的操作有很大的区别,这个是广度优先算法
	// bsf --- Breadth First Search 广度优先算法
	public void bfsOrder() {

		if(root == null) throw new IllegalArgumentException("当前二叉树为NULL");

		bfsOrder(root);

	}
	// 层序遍历 -- 一层一层来,这个跟前面的操作有很大的区别,这个是广度优先算法
	// bsf --- Breadth First Search 广度优先算法
	private void bfsOrder(Node node) {
		// 创建一个队列
		Queue queue = new CommonQueue();

		queue.enqueue(root);

		while (queue != null) {

			Node curNode = (Node) queue.dequeue();
			System.out.print(curNode.value + " ");
			if (curNode.left != null)
				queue.enqueue(curNode.left);
			if (curNode.right != null)
				queue.enqueue(curNode.right);

		}
	}
	// 从二分苏所述中删除最小值所在的节点,返回最小值
	public E removeMin() {
		E ret = min();

		// BEGIN
		root  = removeMin(root);
		// END

		return ret;
	}

	// 删除以node为根的二分搜索树中的最小节点
	// 返回删除节点后新的二分搜索树的根
	private Node removeMin(Node node) {

		if (node.left == null) {
			Node rightNode = node.right;
			node.right = null;
			size--;
			return rightNode;
		}
		// 留存疑问
		node.left = removeMin(node.left);
		return node;
	}

	// 从二分搜索树中删除最大值所在节点
	public E removeMax(){
		E ret = max();
		// BEGIN



		// END
		return ret;
	}

	// 删除掉以node为根的二分搜索树中的最大节点
	// 返回删除节点后新的二分搜索树的根
	private Node removeMax(Node node){

		if (node.right == null) {
			Node leftNode = node.left;
			node.left = null;
			size--;
			return leftNode;
		}

		node.right = removeMax(node.right);
		return node;

	}

	// 判断当前二分搜索树是否存在其他元素
	public boolean isEmpty() {
		return size == 0;
	}
	// 从二分搜索树中删除元素为e的
	public void remove(E e) {

		root = remove(root,e);
	}
	// 删除以node为根的二分搜索树中值为e的节点,递归算法
	// 返回删除节点后新的二分搜索树的根
	public Node remove(Node node,E e) {
		// 当前二分搜索树为NULL,所以要删除的元素不存在 --- 返回null
		if (node == null) return null;

		// 这里面需要再纸上看一下过程
		if (e.compareTo(node.value) < 0) {
			node.left = remove(node.left,e);
			return node;
		} else if(e.compareTo(node.value) > 0) {
			node.right = remove(node.right,e);
			return node;
		} else { // e == node.e
			// 待删除节点左子树为空的情况
			if (node.left == null) {

				Node rightNode = node.right;
				node.right = null;
				size --;
				return rightNode;
			}
			// 待删除节点右子树为空的情况
			if (node.right == null) {
				Node leftNode = node.left;
				node.left = null;
				size --;
				return leftNode;
			}

			// 待删除节点左右子树均不为空的情况
			// 找到比待删除节点大的最小节点,即待删除节点右子树的组消极诶单
			// 用这个节点顶替待删除节点的位置
			/* 后继节点,有大用 */
			Node successor = min(node.right);
			successor.right = removeMin(node.right);
			size++;
			successor.left = node.left;

			node.left = node.right = null;
			size--;
			return successor;
		}
	}
}

睡了睡了,明年的这个节日可不能这个样子了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值