Java Map vs Array(Temp)最后一个索引的排序

时间:2013-04-10 03:41:14

标签: java arrays sorting map hashmap

我看过类似的问题,详细说明了地图的排序和原始数据类型数组的排序,但毫无疑问直接详细说明了一次性Java Map与原始数据类型数组([])之间的区别。

Primary note*我知道'TreeMap'是Java中Map的排序版本(按键),但我不知道TreeMap如何对键进行排序的“幕后花絮” (在添加数据时,或者在添加完成数据之后)?

Primary note 2* Dijkstra的算法in this case不是一个精确的实现。我们只是在M个节点的图G中找到加权边的最短路径。这意味着邻接矩阵(下面看到的格式)的大小为M x M.这是not SMART实现。几乎就像你可以得到的基线...对不起的混乱!


在下面的例子中,我们给出了一个邻接矩阵,其中元素彼此相关('连接'):

0,1,5   // 0 is connected to 1, and the weight of the edge is 5
0,2,7   // 0 is connected to 2, and the weight of the edge is 7
0,3,8   // 0 is connected to 3, and the weight of the edge is 8
1,2,10  // 1 is connected to 2, and the weight of the edge is 10
1,3,7   // 1 is connected to 3, and the weight of the edge is 7
2,3,3   // 2 is connected to 3, and the weight of the edge is 3

但是不要介意输入,只要假设我们有一个值矩阵来操纵。

我们正在考虑将所有可能的路径存储在“最短路径”算法中(我确信75%或更多的人知道Dijkstra的算法)。这是作业,但是一个实施问题,而不是“为我解决这个问题”。

ASSUME矩阵的大小为very large(大小为M x M),大小可能大于50x50。这将导致结果列表中的[50-1]!/2 = 1.52 × 10^64结果,假设我们的算法足够聪明,可以选出重复项而不能找到重复路径的长度(事实并非如此,因为我们在Graph Theory和Java中是noob,所以请不要建议任何算法来避免重复......)。


我的朋友说List中的int [n]索引的临时排序(使用临时变量),其中int [n]是last indexvalue of the shortest path(ALGORITHM_1)比TreeMap(ALGORITHM_2)更快,其中Map的keyvalue of the shortest path

我们正在讨论在尝试查找最短路径的所有lengths时哪种实现会更快。我们可以将它存储为每个路径的最后一个索引(有一个int [],其中最后一个元素是最短路径的值(总和)(数组中的所有元素)(ALGORITHM_1),或者我们可以将该总和存储为地图的关键(ALGORITHM_2)。

因为这是shortest path algorithm(尽管不是很好......),我们需要按长度排序每条路径的结果,这是图中每条边的总和,以便查找最短路径。


所以真正的问题是:对结果进行排序会更快ONLY ONE TIME?通过Map.sort()算法(内置到Java标准库中)或通过创建临时变量来保存每个int []中最近的'length'的值?例如:

myMap.sort(); // Unless TreeMap in Java does 'behind=the-scenes' sorting on keys...
myMap.get(0); // This would return the first element of the map, which is the shortest path

OR

int temp = myList.get(0)[m]; // Store a temp variable that is the 'shortest path'
for( int[] i in myList<int[]>) {
    if (temp > myList.get(i)[m]) { // Check if the current path is shorter than the previous
        temp = myList.get(i)[m]; // Replace temp if current path is shorter
    }
}

Note我还没有真正测试过这些实现,也没有检查过我自己的Java语法,所以我不知道这些语句是否被正确声明了。这只是一个理论问题。哪个会运行得更快?这是我的第三年Java,我不知道HashMap中使用的底层数据结构,也不知道任何一个实现的Big O表示法。

也许知道Java标准的人可以描述在HashMap vs(原始数据类型)[]中使用什么类型的数据结构或实现,以及运行时间的差异可能是ONE-TIME-ONLY种类的结构。

我希望这个调查是有道理的,我感谢任何花时间回答我的问题的人;我总是感谢你们这些慷慨大方的时间和精力,帮助教育新手!

此致      克里斯

3 个答案:

答案 0 :(得分:2)

可能没有必要对数据进行排序以找到最短路径。相反,您可以遍历数据并跟踪您遇到的最短路径。

假设数据存储在Data对象数组中,data.pathLength给出路径长度,

Data[] data; // array of data
Data shortest = data[0]; // initialize shortest variable
for(int i = 1; i < data.length; i++) {
    if(data[i].pathLength < shortest.pathLength)
        shortest = data[i];
}

也就是说,TreeMap是Red-Black Tree,它是一种平衡二叉树的形式。与标准二叉树不同,平衡二叉树将旋转其分支以确保其近似平衡,这确保了log(n)查找和插入。红黑树确保最长的分支不超过最短分支长度的两倍; AVL Tree是一个平衡的二叉树,具有更严格的限制。简而言之,TreeMap将在n * log(n)时间内对其数据进行排序(每次插入的log(n),n个数据点的时间)。假设您正在使用Mergesort或Quicksort或Heapsort等(而不是Bubblesort或其他n ^ 2排序算法),您的一次性数组排序也将在n * log(n)时间内对其数据进行排序。 You cannot do better than n*log(n) with a comparison sort;顺便说一句,你可以使用像Radix Sort这样的转换排序,它有一个很大的O(n)哦,但转换排序通常是内存占用并且表现出较差的缓存行为,所以你通常最好使用其中一个n * log(n)比较排序。

由于TreeMap和你的自定义排序都是n * log(n),这意味着任何一个都没有太大的理论优势,所以只需使用更容易实现的那个。但是,TreeMap的复杂数据结构并不是免费的,因此您的自定义排序算法可能会表现出略微更好的性能,例如:可能是2倍;这可能不值得实现自定义排序的复杂性而不是使用TreeMap,特别是对于一次性排序,但那是你的调用。如果你想要提高你的程序的性能,那么实现一个适合并行化的排序算法(比如Mergesort),看看在多个线程中拆分排序任务时会有多少改进。

答案 1 :(得分:0)

如果您想要 最短路径,则无需进行排序。只需在完成每条路径时跟踪最短路径,并在遇到较短路径时更新最短路径。那最终会给你一个O(n),其中n是路径的数量。无论如何,你无法实际存储10 ^ 64个路径,因此需要截断结果集。

答案 2 :(得分:0)

 how much about the 'behind-the-scenes' of how TreeMap sorts the keys (either while data   
 is being added, or after the data is FINISHED being added)?

TreeMap使用RedBlack树算法(BST的变体),其中操作containsKeygetputremove操作占用O(log(n) ))时间非常好。每次添加元素后,键都会被排序,因为TreeMap定义(在link中)解释了它。排序将采用O(nlog(n))

我不确定你为什么要比较Map类型 - 它使用键,值对Array。您已经提到过将最短路径的长度用作TreeMap中的键,但是您将其作为值放在什么位置?如果您只想存储“路径长度”,我建议将它们放在数组中并使用Arrays.Sort()对它们进行排序,它们也将使用不同的算法Dual-Pivot Quicksort在O(nlog(n))中排序。

希望这有帮助!