[英]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.