算法笔记 - 二叉树搜索树

这篇博客详细介绍了二叉搜索树的概念、构建方法、元素比较方式、遍历算法、树的高度计算、完全二叉树的判断、前驱与后继节点的查找以及节点的删除操作。内容涵盖二叉搜索树的基础知识及其核心操作,适合计算机科学学习者参考。
摘要由CSDN通过智能技术生成

1. 什么是二叉搜索树?

二叉搜索树是二叉树的一种,是应用非常广泛的一种二叉树,英文简称为 BST,又被称为:二叉查找树、二叉排序树。
• 任意一个节点的值都大于其左子树所有节点的值
• 任意一个节点的值都小于其右子树所有节点的值
• 它的左右子树也是一棵二叉搜索树
在这里插入图片描述在这里插入图片描述

2. 如何构建二叉搜索树?

具体在到文件中看,放在了idea->JavaCode中

3. 如何比较元素?

比较重要的一些点,比较元素有多重方式,二叉搜索树默认存放的元素都是具有可比较性的,所以必须定义比较方法。

  1. 基本类型的比较,如果的Integer、String等类型的比较,直接比较即可
  2. Object类型的比较,例如Person类,而且有多个变量时。

第一种:二叉搜索树类的泛型 E extend Comparable,这样Person类就必须要实现接口的方法,实现具体的方法

第二种:定义一个Comparator comparator 对象,在二叉搜索树构造方法中添加Comparator comparator 参数,这样用户在 new BinarySearchTree 的时候,就可以自己new一个比较器来进行个性化比较
在这里插入图片描述

第三种:在第二种的基础上再人性化,用户可以自己定义比较器,也可以不定义,如果没有传递比较器,则强制转换为Comparable类来进行比较
在这里插入图片描述

4. 二叉树遍历

• 前序遍历 - 递归或迭代
• 中序遍历 - 递归或迭代 - 二叉搜索树的中序遍历可能是升序或降序的
• 后序遍历 - 递归或迭代
• 层序遍历 - 利用队列实现,取出对头进行访问,并将其左右子节点入列,然后继续对头出队,循环操作
在这里插入图片描述

5. 如何求二叉树的高度?

利用队列进行求解,levelSize为每一层的元素数量,每遍历一层,就将其左右子节点入队,而队列的个数就是该层结点的数量,然后每出队一个,levelSize–;
在这里插入图片描述

6. 判断是否是一棵完全二叉树?

	public boolean isComplete() {
		if (root == null) return false;
		//队列
		Queue<Node<E>> queue = new LinkedList<>();
		queue.offer(root);
		boolean leaf = false; //叶子结点标记
		while (!queue.isEmpty()) {
			Node<E> node = queue.poll();
			if (leaf && !node.isLeaf()) return false; //判断是否是叶子结点
			if (node.left != null) {
				// 左子节点不为空则将左子节点入队
				queue.offer(node.left);
			} else if (node.right != null) { // node.left == null && node.right != null
				return false;
			}
			if (node.right != null) {
				// 右子节点不为空则将右子节点入队
				queue.offer(node.right);
			} else { // node.right == null
				leaf = true;
			}
		}
		return true;
	}

7.前驱节点

在这里插入图片描述

	private Node<E> predecessor(Node<E> node) {
		if (node == null) return null;
		
		// 前驱节点在左子树当中(left.right.right.right....)
		Node<E> p = node.left;
		if (p != null) {
			while (p.right != null) {
				p = p.right;
			}
			return p;
		}
		
		// 从父节点、祖父节点中寻找前驱节点
		while (node.parent != null && node == node.parent.left) {
			node = node.parent;
		}

		// node.parent == null
		// node == node.parent.right
		return node.parent;
	}

8.后继结点

在这里插入图片描述

	private Node<E> successor(Node<E> node) {
		if (node == null) return null;
		
		// 后驱节点在右子树当中(right.left.left.left....)
		Node<E> p = node.right;
		if (p != null) {
			while (p.left != null) {
				p = p.left;
			}
			return p;
		}
		
		// 从父节点、祖父节点中寻找后继节点
		while (node.parent != null && node == node.parent.right) {
			node = node.parent;
		}

		return node.parent;
	}

9.删除节点

删除度为1的节点

删除度为1的节点时,只需要用子节点替代原节点的位置即可,分三种情况:

  1. 删除左子节点
  2. 删除右子节点
  3. 删除根节点
    在这里插入图片描述

删除度为2的节点

删除度为2的节点,就需要找到被删除节点的前驱节点或者后继结点来替换。
在这里插入图片描述

	private Node<E> node(E element) {
		Node<E> node = root;
		while (node != null) {
			int cmp = compare(element, node.element);
			if (cmp == 0) return node;
			if (cmp > 0) {
				node = node.right;
			} else { // cmp < 0
				node = node.left;
			}
		}
		return null;
	}
	private void remove(Node<E> node) {
		if (node == null) return;
		
		size--;
		
		if (node.hasTwoChildren()) { // 度为2的节点
			// 找到后继节点
			Node<E> s = successor(node);
			// 用后继节点的值覆盖度为2的节点的值
			node.element = s.element;
			// 删除后继节点
			node = s;
		}
		
		// 删除node节点(node的度必然是1或者0)
		Node<E> replacement = node.left != null ? node.left : node.right;
		
		if (replacement != null) { // node是度为1的节点
			// 更改parent
			replacement.parent = node.parent;
			// 更改parent的left、right的指向
			if (node.parent == null) { // node是度为1的节点并且是根节点
				root = replacement;
			} else if (node == node.parent.left) {
				node.parent.left = replacement;
			} else { // node == node.parent.right
				node.parent.right = replacement;
			}
		} else if (node.parent == null) { // node是叶子节点并且是根节点
			root = null;
		} else { // node是叶子节点,但不是根节点
			if (node == node.parent.left) {
				node.parent.left = null;
			} else { // node == node.parent.right
				node.parent.right = null;
			}
		}
	}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值