有效地对列表的元素进行分组

时间:2016-07-12 10:03:44

标签: algorithm performance sorting time-complexity

给定一个元素列表,哪些是通过某个键对元素进行分组的最有效方法?

例如,如果输入为/* "Octile" heuristic */ int h(node n) { int dx = abs(n.x - goal.x); int dy = abs(n.y - goal.y); if (dx > dy) return 14 * dy + 10 * (dx - dy); else return 14 * dx + 10 * (dy - dx); } ,则有效输出可以是{a,c,a,b,c,b,b}{a,a,b,b,b,c,c}

显然,如果密钥的类型遵守订单,则可以使用排序算法,这会给我们带来{b,b,b,c,c,a,a}的复杂性。

但是,密钥可能只是相等而不是订单。例如,O(nlogn)但询问typeof(dog) != typeof(cat)是否有意义。

当然,可以强制排序(例如typeof(dog) < typeof(cat)并使用词法顺序),但由于不需要严格的顺序(仅限分组),我想知道是否有比排序更有效的方法。

2 个答案:

答案 0 :(得分:1)

我会使用未排序的链表和哈希映射来插入点,就像这样(伪代码):

function group_sort(unsorted_list)
  node_map = new hash_map
  sorted_list = new linked_list
  foreach node in unsorted_list
    last_node = node_map.get(type_of(node))
    if last_node found
      sorted_list.insert_after(last_node,node)
    else
      sorted_list.append(node)
      node_map.add(type_of(node),node)
  delete node_map
  return sorted_list

哈希映射查找和插入主要是O(1),哈希映射插入甚至可能很少,具体取决于您的数据。链接列表插入始终为O(1)。这使得函数几乎为O(n),而且肯定是O(nlogn)。

答案 1 :(得分:-1)

您可以将每个项目插入multiset