红黑树——面试相关

1. 简单的介绍下红黑树?

  a. 红黑树是一种平衡二叉查找树(简称平衡树,常见的平衡树有AVL,红黑树。AVL树的性质为:每个结点的左右子树的高度之差的绝对值最多为1。

    //add: 如果再问你什么是平衡树,回答:最大深度不大于log(n),n是树的节点个数。

  b. Java集合中的TreeSetTreeMapC++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。

     //add1:为啥TreeSet和TreeMap不用其他平衡树,比如AVL? 答:虽然红黑树操作的复杂度和AVL是相同的,但是红黑树从不平衡调整到平衡所需操作更少,统计性能更优。

     //add2:TreeSet和HashSet的比较? 

    答:1) TreeSet是用红黑树实现的,操作复杂度O(log(n)),HashSet使用哈希+拉链去冲突法实现的,平均操作复杂度O(1)。所以一般查找HashSet更快。

      2) TreeSet因为是红黑树,本质是一颗二叉排序树,所以元素是排好序的。同时也需要使用Comparator接口,实现 compare方法。(不写的话会使用默认的,没有默认就会抛异常)

        HashSet则需要重写该对象对应类的equals方法和hashCode()方法(不写的话也会使用默认的)。

      3) HashSet可以放入null,但只能放入一个null。TreeSet不能放入null。(TreeSet需要排序,你怎么和一个null比较大小)

 

     c. 红黑树的各项操作(插入、删除、查找等)复杂度都为log(n)

  d. 红黑树的五大特征

    1)节点要么为红色,要么为黑色。(不然为啥叫红黑树;))

    2)根节点为黑色。

    3)叶子节点为黑色。 (这两个简直送分,最上面和最下面都是黑的)

    4)每个红色节点的左右孩子都是黑色。 (保证了从根节点到叶子节点不会出现连续两个红色节点)

    5)从任意节点到其每个叶子节点的所有路径,都包含相同数目的黑色节点。(4,5是使得红黑树为平衡树的关键)

 

  

### 关于红黑树面试题目及解答 #### 红黑树简介 红黑树是一种自平衡二叉搜索树,在最坏情况下仍然能保持O(log n)的时间复杂度,这使得其成为许多应用的理想选择。为了维持这种性能特性,红黑树遵循一系列严格的规定来确保树的高度尽可能低。 #### 面试问题一:描述红黑树的特点及其性质? 红黑树具有以下五个重要属性[^4]: 1. 节点要么是红色,要么是黑色; 2. 根总是黑色; 3. 所有的叶子(NIL节点)都是黑色; 4. 如果一个内部节点是红色,则它的两个子节点均为黑色。(即不存在相邻的红色节点) 5. 对任意给定节点而言,从该节点到达其可达叶子的所有路径上均含有相同数量的黑色节点。 这些规则共同作用以保证即使是在极端条件下也能接近对数级别的访问时间。 #### 面试问题二:为什么说红黑树能够实现高效的插入删除操作? 由于每次插入或移除元素之后都会重新调整颜色并旋转某些部分从而恢复上述提到的颜色约束条件,因此可以有效地防止树形结构变得不平衡而影响效率。具体来说: - **插入**: 当新加入的关键字违反了其中任何一条规定时,会通过改变一些节点的颜色以及执行一次或多次单旋/双旋动作来进行修正。 - **删除**: 类似地,在去除某个特定项的过程中也可能引起违规情况发生,这时同样采取适当措施使整棵树恢复正常形态。 以上过程虽然增加了额外开销但是总体来看还是非常值得的因为它极大地提高了查询速度。 ```java // Java code snippet demonstrating a simple insertion into a Red Black Tree. public class RBTNode { boolean color; int key; RBTNode left, right, parent; public void insertFixup(RBTNode z){ while(z.parent.color == 'red'){ if(parentOf(z.parent)=='left child'){ // Case where uncle is black or null RBTNode y = z.getUncle(); if(y!=null && y.color=='red') { // Case 1: Uncle red -> Recolor and move up the tree z.parent.color='black'; y.color='black'; grandparentOf(z).color='red'; z=grandparentOf(z); } else{ if(z==rightChildOfParent()){//Case 2: Right leaning subtree with black uncle-> Rotate Left then proceed as case 3 z=z.parent; rotateLeft(z); } // Case 3: Left leaning subtree with black uncle -> Color flip + single rotation on gp z.parent.color='black'; grandparentOf(z).color='red'; rotateRight(grandparentOf(z)); } }else{ /* Mirror of above when P is right child */ } } root.color='black'; } } ``` 此代码片段展示了如何处理因插入而导致的可能破坏红黑树特性的状况之一——连续两次出现红色连接的情况,并对其进行修复。 #### 面试问题三:给出一段Python程序用于验证一棵已知二叉树是否满足红黑树的要求? 下面是一个简单的 Python 函数用来检测输入的一棵二叉树是不是有效的红黑树: ```python class TreeNode: def __init__(self, val=0, color="BLACK", left=None, right=None): self.val = val self.color = color self.left = left self.right = right def validate_rb_tree(root): """Check whether given binary search tree satisfies all properties of RB Trees.""" def helper(node, depth): nonlocal min_depth, max_depth if not node: if min_depth == float('inf'): min_depth = depth elif abs(depth-min_depth)>1: return False max_depth=max(max_depth,depth) return True # Check property violations at current level if ((node.color != "RED" and node.color != "BLACK") or (node.color=="RED" and getattr(node,'parent',None)!=None and node.parent.color=="RED")) : return False lres,rres=True,True if node.left:lres=helper(node.left ,depth+(node.color=="BLACK")) if node.right:rres=helper(node.right,depth+(node.color=="BLACK")) return lres and rres min_depth,max_depth=float('inf'),float('-inf') res = helper(root,root.color=="BLACK") return res and (min_depth<=max_depth+1) if __name__ == "__main__": # Example usage pass ``` 这段脚本实现了递归遍历整个树的过程,同时记录每条路径上的黑高度,并检查是否存在非法着色模式。最终返回布尔值指示传入的对象是否构成合法的红黑树实例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值