代码之家  ›  专栏  ›  技术社区  ›  Jeff Meatball Yang

从邻接表创建树的最有效方法

  •  6
  • Jeff Meatball Yang  · 技术社区  · 15 年前

    我有一个对象的邻接列表(用键及其父键从sql数据库加载的行),需要用它来构建无序树。它肯定没有周期。

    这占用了wayyy太长时间(在大约5分钟内,870k个节点中仅处理了~3k个节点)。运行在我的工作站Core2Duo上,内存充足。

    有什么办法让这个更快的吗?

    public class StampHierarchy {
        private StampNode _root;
        private SortedList<int, StampNode> _keyNodeIndex;
    
        // takes a list of nodes and builds a tree
        // starting at _root
        private void BuildHierarchy(List<StampNode> nodes)
        {
            Stack<StampNode> processor = new Stack<StampNode>();
            _keyNodeIndex = new SortedList<int, StampNode>(nodes.Count);
    
            // find the root
            _root = nodes.Find(n => n.Parent == 0);
    
            // find children...
            processor.Push(_root);
            while (processor.Count != 0)
            {
                StampNode current = processor.Pop();
    
                // keep a direct link to the node via the key
                _keyNodeIndex.Add(current.Key, current);  
    
                // add children
                current.Children.AddRange(nodes.Where(n => n.Parent == current.Key));
    
                // queue the children
                foreach (StampNode child in current.Children)
                {
                    processor.Push(child);
                    nodes.Remove(child); // thought this might help the Where above
                }
            }
        }
    }
    
        public class StampNode {
             // properties: int Key, int Parent, string Name, List<StampNode> Children
        }
    
    2 回复  |  直到 15 年前
        1
  •  4
  •   Ian Mercer    15 年前
    1. 将节点放入已排序的列表或字典中。

    2. 扫描该列表,选择每个节点,在同一列表中查找其父节点(二进制搜索或字典查找),将其添加到父节点的子集合中。

    把这个放在树上不需要堆起来。

        2
  •  2
  •   Gary Linscott    15 年前

    SortedList不是在这种情况下使用的好容器。插入操作(对add()的重复调用)是o(n),因为它在内部表示为一个平面列表。使用字典代替sortedlist将是一个很大的改进,因为它是o(1)分期插入时间。