作为项目要求的一部分,我需要在列表列表中搜索节点(字符串)。该集由N个列表组成,每个列表都是由L个节点组成的列表。这里N具有大的值,通常> = 5000并且L是=< 100.
哪种数据结构最适合转换每个列表的L个节点,以便更快更轻松地进行搜索?
我不确定是否以某种树结构的形式转换列表,因为列表的节点是字符串(我可以手动为每个节点分配一些编号并将其转换为合适的树结构,以便那搜索会更快?如果是,那么树结构将是理想的)
提前感谢您提供任何帮助。
答案 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)
我实际上不会改变数据结构。列表列表是一个非常好的数据结构,原因有两个:
因此,根据您的编程语言,可以执行双循环:
for all elements in mainlist:
for all elements in sublist:
if element == target:
break;
endif
endfor
endfor
甚至可以更好地使用foreach循环:
在任何情况下,foreach都非常有效,并会迭代你的所有列表并停止(一旦你说休息;)。所有其他转换可能会花费你很多计算。
另一种选择是因为izaera说使用散列图但是你的代码的其余部分(如果你想操纵列表)会变得有点困难,所以保持简单。 :)