合并含少量损坏节点的两棵AVL树的高效算法咨询
AVL树合并+剔除损坏节点的优化思路
朴素算法的核心瓶颈来自两部分:1. 提前做k次损坏节点删除产生的
O(k log n)开销(k为损坏节点数,n为树1节点数);2. 将树1剩余节点逐个插入树2时,每次插入都要做AVL平衡调整,整体开销达到O((n-k) log(m + n))(m为树2节点数),数据规模越大性能损耗越明显。
以下是可行的优化思路:
- 思路1:有序序列合并重建法(综合效率最高)
利用AVL树中序遍历天然得到有序序列的特性,跳过单独删除损坏节点、逐个插入的高开销步骤,流程如下:- 先将已知的损坏节点key列表排序,得到有序损坏集合
bad_keys,开销O(k log k),因k远小于n,这一步开销几乎可以忽略 - 中序遍历树1,遍历过程中用双指针法匹配
bad_keys,直接跳过损坏节点,得到树1有效节点的有序序列,开销O(n) - 中序遍历树2得到其所有节点的有序序列,开销
O(m) - 合并两个有序序列,得到整体有序的全量有效节点序列,开销
O(n + m) - 用有序序列自底向上构建新的AVL树,这一步不需要额外做平衡调整,直接按平分中点作为根、左右子序列递归构建子树即可,开销
O(n + m)
整体时间复杂度为O(n + m + k log k),远优于朴素算法,尤其适合n、m规模较大的场景。
- 先将已知的损坏节点key列表排序,得到有序损坏集合
- 思路2:保留原树2结构的批量插入优化
如果要求不能重建树、必须基于原树2做修改,可以避免逐个插入的开销:- 同样先通过中序遍历树1过滤损坏节点,得到有效节点的有序序列S
- 采用有序序列批量插入AVL树的优化方案:不需要逐个插入每个节点,而是找到S在树2中的插入区间,一次性将区间内的节点批量挂载后统一做平衡调整,整体开销可优化到
O(log m + n),相比朴素的逐个插入O(n log(m + n))有明显提升。
- 通用小优化:跳过提前删除损坏节点的步骤
不管用哪种优化方案,都不需要像朴素算法一样先遍历损坏列表逐个删除树1的节点,遍历树1的过程中直接跳过损坏key即可,可直接节省O(k log n)的删除操作开销。
内容的提问来源于stack exchange,提问作者Chaot1c
相关产品推荐
相关产品推荐

