簡體   English   中英

用Java對圖的邊緣進行排序(基於鄰接列表表示)

[英]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;
}

例如

  • 0:<1,55>-> <2,54> //節點0連接到邊緣權重為55的節點1和節點邊緣權重為54的節點2
  • 1:<0,43>-> <2,44> //節點1連接到邊緣權重為43的節點0和節點2邊緣權重為44的節點

我需要獲得按重量排序的邊緣列表,但我不知道如何去做。 我正在嘗試實施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

這將代表程序內部的圖形(從示例中復制):

  • 節點0:邊緣(節點0,節點1,55),邊緣(節點0,節點2,54)
  • 節點1:邊緣(節點1,節點0,43),邊緣(節點1,節點2,44)

要回答您的問題 ,讓我們找到按邊緣權重排序的邊緣:

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()Javadocsort()方法使用合並排序,合並排序在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM