c++ - 节点数小于和大于某个节点的节点数

标签 c++ algorithm graph tree graph-algorithm

给定一棵树,计算每个顶点在其子树中大于该顶点的节点数和小于该顶点的节点数。

我可以通过深度优先搜索 (DFS) 找到单个顶点的答案,但对每个顶点都这样做肯定会花费很多时间。

我们能否更快地解决问题?

最佳答案

一种更有效的方法:

一种更有效的方法是执行后序并使用二叉​​搜索树类型映射(可能在 C++ 中,排序映射实现应该已经使用某种红黑树)来存储键及其计数。

对树进行后序遍历。 在遍历后的每个节点:

a) 对于更大的节点:

获取 BST 类型映射中当前节点的下一个最高值(这应该在 O( log n ) 中完成并计算它下面的所有值。(这将节省大量时间,尤其是如果树是平衡的),但如果树是不平衡的,将会很昂贵。

b) 对于较小的节点:

获取 BST 类型映射中当前节点的下一个最小值(这应该在 O( log n ) 中完成并计算它上面的所有值。

//map - sorted map with keys and their count
//greater_map - unordered map that contains node as key and count of nodes greater than key node.
//lesser_map - unordered map that contains node as key and count of nodes lesser than key node.

post_order( Node root ) 
   if ( root == null ) return;

   for each child in root.children:
       post_order( child )

   int next_higher_key = find_next_higher_key( map, root_key )
   greater_map.insert(root, count_all_values_greater_than_equal_to(next_higher_key, map) )

   int next_smaller_key = find_next_smaller_key( map, root_key )
   lesser_map.insert(root, count_all_values_lesser_than_equal_to(next_smaller_key, map) )

   if ( !map[root_key] )
      map.insert( root_key, 1 )
   else
      map.insert( root_key, map[root_key] + 1 )

效率较低的方法:

对树进行一次深度优先搜索遍历。在完成遍历后的每个节点,将较大节点和较小节点的数量存储在两个映射中。键将是您刚刚完成遍历的节点,值将分别是大于当前节点的节点数和小于当前节点的节点数。从 map 上,您可以轻松获得对于任何给定节点来说更大或更小的节点数。

伪代码:


list_of_nodes dfs( Node root ) {
   list_of_nodes thisList = new list_of_nodes;
   if ( root == null ) return thisList;
   thisList.push( root );

   for each child in root.children:
       list_of_nodes childList = dfs( child )
       thisList.addAll( childList )

   int greater = 0, lesser = 0
   for each node in thisList:
       if node_value > root_value
           greater++
       else if node_value < root_value
           lesser++

   greatermap.insert( root, greater )
   lessermap.insert( root, lesser )

   return thisList

要获取任何给定节点的更大、更小节点的数量,您只需访问 map 即可。

dfs( root_of_tree );
greater_num = greatermap[node]
lesser_num = lessermap[node]

关于c++ - 节点数小于和大于某个节点的节点数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57392985/

相关文章:

c++ - 如果在运行时可用,是否自动使用 AVX/SSE?

c++ - 指向指针的 Static_cast 整数地址

C++ 变量外部声明

algorithm - 算法时间复杂度总是 O(1) 优于 O(n)?

双向图的算法

graph - 如何为Sphinx中的所有模块添加继承图?

c++ - 初始化在类的私有(private)成员中声明的静态容器数据

algorithm - 联立方程的最小二乘解

android - 我如何检查一个游戏板是否连续有 4 个相同的 block ? (安卓)

algorithm - 有向图中顶点和边的关系