AVL树在薪资统计场景下的解法验证与秩查找机制技术问询
问题解答
i. 你的解法是否能得到正确结果?
答案是否定的,存在两个关键缺陷:
- 整数节点数与比例的矛盾:总员工数
n不一定是10的整数倍(比如n=11时,10%为1.1),但AVL树的size字段是整数,你无法找到size等于非整数的节点。即使n是10的倍数,后续逻辑依然有误。 - 对AVL树结构的误解:你假设找到
size=n/10的节点k后,其整棵子树就是薪资最高的10%员工,但AVL树中k的左子树所有节点薪资都小于k,这些节点显然不属于“最高10%”的范畴。真正的最高10%是树中薪资排名最靠前的n/10个节点(极端特例除外),它们分散在树的最右侧路径及相关子树中,而非某一个完整子树。
ii. AVL树秩查找流程及所需增强字段解析
核心定义先明确
这里的秩指节点的「从小到大排名」:秩1对应薪资最低的员工,秩n对应薪资最高的员工。官方解法要找的是秩为9n/10的节点v,这样薪资大于v的员工数恰好是n - 9n/10 = n/10,符合“最高10%”的需求。
秩查找的递归流程(以找第m小节点为例,m=9n/10)
每个节点需存储size字段(左子树节点数 + 右子树节点数 + 1),递归步骤如下:
- 对当前节点
node,计算左子树节点数left_size = node.left ? node.left.size : 0(左子树所有节点薪资都小于node)。 - 如果
left_size + 1 == m:当前node就是目标节点——左子树有left_size个比它小的节点,加上它自己正好是第m小的节点。 - 如果
m <= left_size:目标节点在左子树中,递归搜索node.left,目标仍为第m小的节点。 - 如果
m > left_size + 1:目标节点在右子树中,递归搜索node.right,目标调整为第m - (left_size + 1)小的节点(左子树+当前节点已占据left_size+1个排名,右子树的节点排名从该值后开始计算)。
实现秩查找所需的增强字段
仅需size字段:它让我们能在O(1)时间内判断目标节点的位置,保证秩查找的时间复杂度为O(logn)(AVL树的高度)。如果没有size,只能遍历整棵树,时间复杂度退化为O(n),失去了AVL树的高效性。
补充:高效计算薪资大于v的节点总和
找到节点v后,总和由两部分组成:
v的右子树总和(v.right.sum):右子树所有节点薪资都大于v。- 回溯路径中符合条件的祖先节点及右子树:当
v是父节点x的左孩子时,x的薪资大于v,且x的右子树所有节点薪资都大于x(自然大于v),因此需要累加x.key + x.right.sum;若v是x的右孩子,则x的薪资小于v,无需累加。
将两部分总和相加后除以n/10,就得到最高10%员工的平均薪资。
内容的提问来源于stack exchange,提问作者MathCurious
相关产品推荐
相关产品推荐

