[英]Sorting edges of a graph (based on Adjacency List representation) in Java
I have a graph which stores it's edges using a HashMap as follows : 我有一个图,使用HashMap将其边缘存储如下:
HashMap<Integer,LinkedList<Node>> adj;
where Node is defined ; 定义Node的位置;
class Node
{
int number;
int weight;
}
eg 例如
I need to get a list of edges in sorted order by weight and I have no clue how to go about it. 我需要获得按重量排序的边缘列表,但我不知道如何去做。 I am trying to implement Kruskal's MST.
我正在尝试实施Kruskal的MST。
Is it possible to sort the graph I have defined? 是否可以对我定义的图进行排序? If not please suggest a better way of storing it.
如果没有,请提出一种更好的存储方式。
Let's start by creating an Edge
class: 让我们从创建
Edge
类开始:
class Edge implements Comparable<Edge> { // Important: must implement Comparable. More on this later
public Node first; // first connected node
public Node second; // second connected node
public int weight; // move edge weight to Edge class
@Override
public int compareTo(Edge e) {
if (weight < e.weight) {
return -1;
} else if (weight > e.weight) {
return 1;
} else {
return 0;
}
}
}
Because the weight
variable is in the Edge
class, it isn't needed in Node
, so you can remove it: 由于
weight
变量在Edge
类中,因此Node
不需要它,因此可以将其删除:
class Node {
public int number;
// add more variables later is you need here
}
Now, for your program (if there isn't a requirement against it), I would define your list like this: 现在,对于您的程序(如果不需要它),我将像这样定义您的列表:
HashMap<Node, List<Edge>> adj; // use any list implementation you want
This will represent the graph like this inside your program (copied from your example): 这将代表程序内部的图形(从示例中复制):
To answer your question , lets find the edges sorted by edge weight: 要回答您的问题 ,让我们找到按边缘权重排序的边缘:
ArrayList<Edge> sortedEdges = new ArrayList<Edge>();
for (List<Edge> connectedEdges : adj.values()) {
sortedEdges.addAll(connectedEdges);
}
Collections.sort(sortedEdges);
This simply takes all the Edge
s in adj
and puts them all in one list, and then sorts them according to their weight (because we made Edge
extend Comparable<Edge>
). 这只是将所有
Edge
放入adj
并将它们全部放入一个列表中,然后根据它们的权重对其进行排序(因为我们使Edge
扩展了Comparable<Edge>
)。 As per the Javadoc on Collections.sort()
, the sort()
method uses merge sort, which runs in O(nlog(n))
time: 根据
Collections.sort()
上的Javadoc , sort()
方法使用合并排序,合并排序在O(nlog(n))
时间运行:
Implementation note: This implementation is a stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when the input array is partially sorted, while offering the performance of a traditional mergesort when the input array is randomly ordered.
实施注意事项:此实现是一种稳定的,自适应的,迭代的归并排序,当对输入数组进行部分排序时,所需的比较少于n lg(n),而当对输入数组进行随机排序时,它提供了传统归并排序的性能。
Getting the list of all Edge
s by adj.values
takes O(n)
time (see this ), so the total time complexity of getting the list of edges sorted by weight will be O(n) + O(nlog(n))
= O(nlog(n))
. 通过
adj.values
获取所有Edge
的列表需要O(n)
时间(请参阅此 ),因此,获取按权重排序的边缘列表的总时间复杂度将为O(n) + O(nlog(n))
= O(nlog(n))
。
So there you go. 所以你去了。 I hope this helped :)
我希望这可以帮助:)
If you have the freedom to change the way nodes are represented, I would like to suggest changing it. 如果您可以自由更改节点表示的方式,建议您更改它。 Currently the
Node
class really represents an edge (and a node is represented by Integer
, ie, keys to the adj
variable. 当前,
Node
类实际上表示一条边(并且节点由Integer
表示,即adj
变量的键。
For example, the following seems more natural: 例如,以下似乎更自然:
Set<Node> nodes = new HashSet<>(); // The enclosing class keeps track of all nodes.
// Represents each node.
class Node {
int nodeId = /* ... */;
// The Node class keeps track of its neighbors, sorted by their weights.
SortedMap<Integer,Node> edges = new TreeMap<>(Collections.reverseOrder());
}
Then, whenever you need to do things in the descending order of the weight, you could do something like: 然后,每当您需要按权重降序执行操作时,可以执行以下操作:
void method(Node node) {
Iterator<Integer> iter = node.edges.keySet().iterator(); // Iterates in descending order.
while(iter.hasNext()) {
int weight = iter.next();
Node neighbor = node.edges.get(weight);
doSomething( /* ... */ );
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.