[英]Sorting edges of a graph (based on Adjacency List representation) in Java
我有一个图,使用HashMap将其边缘存储如下:
HashMap<Integer,LinkedList<Node>> adj;
定义Node的位置;
class Node
{
int number;
int weight;
}
例如
我需要获得按重量排序的边缘列表,但我不知道如何去做。 我正在尝试实施Kruskal的MST。
是否可以对我定义的图进行排序? 如果没有,请提出一种更好的存储方式。
让我们从创建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;
}
}
}
由于weight
变量在Edge
类中,因此Node
不需要它,因此可以将其删除:
class Node {
public int number;
// add more variables later is you need here
}
现在,对于您的程序(如果不需要它),我将像这样定义您的列表:
HashMap<Node, List<Edge>> adj; // use any list implementation you want
这将代表程序内部的图形(从示例中复制):
要回答您的问题 ,让我们找到按边缘权重排序的边缘:
ArrayList<Edge> sortedEdges = new ArrayList<Edge>();
for (List<Edge> connectedEdges : adj.values()) {
sortedEdges.addAll(connectedEdges);
}
Collections.sort(sortedEdges);
这只是将所有Edge
放入adj
并将它们全部放入一个列表中,然后根据它们的权重对其进行排序(因为我们使Edge
扩展了Comparable<Edge>
)。 根据Collections.sort()
上的Javadoc , sort()
方法使用合并排序,合并排序在O(nlog(n))
时间运行:
实施注意事项:此实现是一种稳定的,自适应的,迭代的归并排序,当对输入数组进行部分排序时,所需的比较少于n lg(n),而当对输入数组进行随机排序时,它提供了传统归并排序的性能。
通过adj.values
获取所有Edge
的列表需要O(n)
时间(请参阅此 ),因此,获取按权重排序的边缘列表的总时间复杂度将为O(n) + O(nlog(n))
= O(nlog(n))
。
所以你去了。 我希望这可以帮助:)
如果您可以自由更改节点表示的方式,建议您更改它。 当前, Node
类实际上表示一条边(并且节点由Integer
表示,即adj
变量的键。
例如,以下似乎更自然:
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());
}
然后,每当您需要按权重降序执行操作时,可以执行以下操作:
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.