以树结构的形式转换列表列表以进行有效搜索

时间:2012-12-24 07:58:01

标签: list search tree

作为项目要求的一部分,我需要在列表列表中搜索节点(字符串)。该集由N个列表组成,每个列表都是由L个节点组成的列表。这里N具有大的值,通常> = 5000并且L是=< 100.

  1. 哪种数据结构最适合转换每个列表的L个节点,以便更快更轻松地进行搜索?

    我不确定是否以某种树结构的形式转换列表,因为列表的节点是字符串(我可以手动为每个节点分配一些编号并将其转换为合适的树结构,以便那搜索会更快?如果是,那么树结构将是理想的)

  2. 提前感谢您提供任何帮助。

3 个答案:

答案 0 :(得分:1)

我建议两种结构:

1)订购字符串列表,以便您可以进行二进制搜索(复杂度:O(n * log(n))以便插入和搜索)

2)更好:将字符串放在散列映射中,以便插入和搜索为O(1)。

您也可以使用B树(http://en.wikipedia.org/wiki/B-tree),但它类似于保持列表的排序,我认为这会导致更多的开销。

如果表现有问题,我肯定会选择(2)。

答案 1 :(得分:1)

我建议使用哈希映射或排序树,将字符串(城市名称)映射到表单的元组(index_in_main_list,index_in_sublist)。

在哈希映射的情况下,这允许对字符串进行恒定时间查找,同时仍允许迭代原始列表。

你提到了城市和地下旅行路线的字符串。由于城市可能会铺设几条旅行路线,因此每个哈希值应保留几个元组。

例如,在Java中,类型声明将是:

public class IndexTuple {
    public final int fst;
    public final int snc;
    public IndexTuple(int fst, int snd) {
        this.fst = fst;
        this.snd = snd;
    }
}

HashMap<String, ArrayList<IndexTuple>> lookupMap;

// The sublists of cities. I've used an ArrayList as example, but
// that's language and context dependent. Use arrays if the size
// won't change.
ArrayList<ArrayList<String>> cities;

填充数据结构变得非常简单,只需在列表上运行并添加:

for(int i = 0; i < cities.size(); i++) {
    for(int j = 0; j < cities.get(i).size(); j++) {
        String city = cities.get(i).get(j));
        if(!lookupMap.containsKey(city) {
            lookupMap.put(city, new ArrayList<IndexTuple>());
        }
        lookupMap.get(city).add(new IndexTuple(i, j));
    }
}

编辑:请注意,如果您不必遍历原始列表,则可以在构建散列映射或树之后将其删除。记住指数时,您仍然可以找到该城市所属的序列。重建迭代列表将是一种混乱。

答案 2 :(得分:0)

我实际上不会改变数据结构。列表列表是一个非常好的数据结构,原因有两个:

  1. 您可以使用像Mainlist(5)(7)这样的索引,并且基本上将列表视为一个大的2D数组(具有不同的列大小)。
  2. 易于“想象”在你的头脑中,以便进一步编码将更容易
  3. 因此,根据您的编程语言,可以执行双循环:

    for all elements in mainlist:
       for all elements in sublist:
           if element == target:
               break;
           endif
        endfor
    endfor
    

    甚至可以更好地使用foreach循环:

    在任何情况下,foreach都非常有效,并会迭代你的所有列表并停止(一旦你说休息;)。所有其他转换可能会花费你很多计算。

    另一种选择是因为izaera说使用散列图但是你的代码的其余部分(如果你想操纵列表)会变得有点困难,所以保持简单。 :)