Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中对图的边进行排序(基于邻接列表表示)_Java_Sorting_Data Structures_Graph_Minimum Spanning Tree - Fatal编程技术网

在Java中对图的边进行排序(基于邻接列表表示)

在Java中对图的边进行排序(基于邻接列表表示),java,sorting,data-structures,graph,minimum-spanning-tree,Java,Sorting,Data Structures,Graph,Minimum Spanning Tree,我有一个使用HashMap存储其边的图,如下所示: HashMap<Integer,LinkedList<Node>> adj; 乙二醇 0:->//节点0连接到具有边权重55的节点1和具有边权重54的节点2 1:->//节点1连接到具有边权重43的节点0和具有边权重的节点2 边重44 我需要得到一个按重量排序的边列表,但我不知道该怎么做。我正在尝试实现Kruskal的MST 可以对我定义的图进行排序吗?如果没有,请建议更好的存储方式 让我们先创建一个Edge类:

我有一个使用HashMap存储其边的图,如下所示:

HashMap<Integer,LinkedList<Node>> adj;
乙二醇

  • 0:->//节点0连接到具有边权重55的节点1和具有边权重54的节点2
  • 1:->//节点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;
        }
    }
}
现在,对于您的程序(如果没有针对它的要求),我将如下定义您的列表:

HashMap<Node, List<Edge>> adj; // use any list implementation you want
HashMap adj;//使用您想要的任何列表实现
这将在您的程序中表示如下图形(从您的示例中复制):

  • 节点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);
ArrayList sortedges=new ArrayList();
对于(列出连接的边:adj.values()){
分类数据。添加所有(连接数据);
}
收集。分类(分类);
这只需将
adj
中的所有
Edge
放在一个列表中,然后根据它们的权重对它们进行排序(因为我们使
Edge
extend)。根据,
sort()
方法使用合并排序,它在
O(nlog(n))
时间内运行:

实现说明:此实现是一种稳定、自适应、迭代的mergesort,当输入数组部分排序时,需要的比较远远少于n lg(n),而当输入数组随机排序时,它提供了传统mergesort的性能

通过
adj.值获取所有
Edge
s的列表需要
O(n)
时间(请参见),因此获取按权重排序的边列表的总时间复杂度将是
O(n)+O(nlog(n))
=
O(nlog(n))


好了。我希望这会有所帮助:)

如果您可以自由更改节点的表示方式,我建议您进行更改。目前,
节点
类实际上代表一条边(节点由
整数
表示,即
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());
}
Set nodes=new HashSet();//封闭类跟踪所有节点。
//表示每个节点。
类节点{
int nodeId=/*…*/;
//节点类跟踪其邻居,按其权重排序。
SortedMap edges=新树映射(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( /* ... */ );
    }
}
void方法(节点){
迭代器iter=node.edges.keySet().Iterator();//按降序迭代。
while(iter.hasNext()){
int-weight=iter.next();
节点邻居=Node.edges.get(权重);
剂量测定法(/*…*/);
}
}

旁注:你可以摆脱那一个
O(n)
通过实现您自己的合并排序,在迭代列表时对列表进行排序。我不确定这样做可以节省多少时间…此方法仅对一个节点的边进行排序。OP希望获得整个图中所有边的列表,按权重排序。
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( /* ... */ );
    }
}