繁体   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