Java手写Prim算法和Prim算法应用拓展案例

Java手写Prim算法和Prim算法应用拓展案例

1. 算法思维导图

以下是使用Mermanid代码表示的Prim算法实现原理:

初始化图G
初始化集合S 将任意节点加入S
初始化边集E 将与S中节点相连的边加入E
从E中选择权值最小的边e 并将其加入到集合T中
将e的另一端节点加入S
将与新加入S中的节点相连的边加入E
重复步骤D到F 直到S包含所有节点

2. 该算法的手写必要性和市场调查

手写Prim算法的必要性在于深入理解算法的原理和实现细节,从而能够更好地应用和优化该算法。市场调查显示,Prim算法在网络规划、最小生成树问题等领域有着广泛的应用,具有很高的市场需求和潜力。

3. 该算法的详细介绍和步骤

Prim算法是一种用于解决最小生成树问题的贪心算法。它从一个节点开始,逐步扩展生成树,直到包含所有节点为止。以下是Prim算法的详细步骤:

  1. 初始化图G和集合S,将任意节点加入S。
  2. 初始化边集E,将与S中节点相连的边加入E。
  3. 从E中选择权值最小的边e,并将其加入到集合T中。
  4. 将e的另一端节点加入S。
  5. 将与新加入S中的节点相连的边加入E。
  6. 重复步骤3到5,直到S包含所有节点。

4. 该算法的手写实现总结和思维拓展

通过手写实现Prim算法,我们深入理解了算法的原理和实现细节。该算法的思维拓展可以包括以下方面:

  • 优化算法的时间复杂度和空间复杂度。
  • 将算法应用于不同类型的图结构。
  • 探索其他贪心算法和最小生成树算法的联系和区别。

5. 该算法的完整代码

以下是Java语言实现的Prim算法的完整代码,每行代码都附有注释:

import java.util.*;

public class PrimAlgorithm {
    public static void main(String[] args) {
        // 构建图的邻接矩阵表示
        int[][] graph = {
            {0, 2, 0, 6, 0},
            {2, 0, 3, 8, 5},
            {0, 3, 0, 0, 7},
            {6, 8, 0, 0, 9},
            {0, 5, 7, 9, 0}
        };

        prim(graph);
    }

    public static void prim(int[][] graph) {
        int n = graph.length; // 图的节点数

        int[] parent = new int[n]; // 保存最小生成树的父节点
        int[] key = new int[n]; // 保存节点到最小生成树的最小权值

        boolean[] visited = new boolean[n]; // 记录节点是否已经访问过

        // 初始化key数组为无穷大
        Arrays.fill(key, Integer.MAX_VALUE);

        // 从第一个节点开始构建最小生成树
        key[0] = 0;
        parent[0] = -1;

        for (int i = 0; i < n - 1; i++) {
            int minKeyIndex = findMinKey(key, visited); // 找到key数组中最小值对应的节点

            visited[minKeyIndex] = true; // 将该节点标记为已访问

            // 更新与该节点相邻的节点的key值和parent值
            for (int j = 0; j < n; j++) {
                if (graph[minKeyIndex][j] != 0 && !visited[j] && graph[minKeyIndex][j] < key[j]) {
                    parent[j] = minKeyIndex;
                    key[j] = graph[minKeyIndex][j];
                }
            }
        }

        // 输出最小生成树
        System.out.println("边\t权值");
        for (int i = 1; i < n; i++) {
            System.out.println(parent[i] + " - " + i + "\t" + graph[i][parent[i]]);
        }
    }

    public static int findMinKey(int[] key, boolean[] visited) {
        int minKey = Integer.MAX_VALUE;
        int minKeyIndex = -1;

        for (int i = 0; i < key.length; i++) {
            if (!visited[i] && key[i] < minKey) {
                minKey = key[i];
                minKeyIndex = i;
            }
        }

        return minKeyIndex;
    }
}

6. 该算法的应用前景调研

Prim算法作为一种解决最小生成树问题的常用算法,具有广泛的应用前景。它可以应用于以下领域:

  • 网络规划:Prim算法可以用于构建网络拓扑结构,以实现最小成本的网络连接。
  • 电力系统:Prim算法可以用于优化电力系统的供电路径,以提高电力传输效率。
  • 物流管理:Prim算法可以用于优化物流路径,以降低物流成本和提高物流效率。

7. 该算法的拓展应用案例

以下是Prim算法的三个拓展应用案例的完整代码和步骤描述:

7.1 案例1: 最小生成树的可视化

import java.awt.*;
import java.util.*;
import javax.swing.*;

public class PrimVisualization extends JPanel {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private static final int RADIUS = 20;

    private int[][] graph;
    private Set<Integer> minTree;
    private Set<Integer> visited;

    public PrimVisualization(int[][] graph) {
        this.graph = graph;
        this.minTree = new HashSet<>();
        this.visited = new HashSet<>();
        this.setPreferredSize(new Dimension(WIDTH, HEIGHT));

        prim();
    }

    private void prim() {
        int n = graph.length;
        int[] parent = new int[n];
        int[] key = new int[n];
        boolean[] inTree = new boolean[n];

        Arrays.fill(key, Integer.MAX_VALUE);

        key[0] = 0;
        parent[0] = -1;

        for (int i = 0; i < n - 1; i++) {
            int u = findMinKey(key, inTree);
            inTree[u] = true;

            for (int v = 0; v < n; v++) {
                if (graph[u][v] != 0 && !inTree[v] && graph[u][v] < key[v]) {
                    parent[v] = u;
                    key[v] = graph[u][v];
                }
            }
        }

        for (int i = 1; i < n; i++) {
            minTree.add(parent[i]);
            minTree.add(i);
        }
    }

    private int findMinKey(int[] key, boolean[] inTree) {
        int minKey = Integer.MAX_VALUE;
        int minKeyIndex = -1;

        for (int i = 0; i < key.length; i++) {
            if (!inTree[i] && key[i] < minKey) {
                minKey = key[i];
                minKeyIndex = i;
            }
        }

        return minKeyIndex;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int n = graph.length;

        // 绘制节点
        for (int i = 0; i < n; i++) {
            int x = (i % 4 + 1) * WIDTH / 5;
            int y = (i / 4 + 1) * HEIGHT / 3;
            g.setColor(minTree.contains(i) ? Color.RED : Color.BLACK);
            g.fillOval(x - RADIUS, y - RADIUS, 2 * RADIUS, 2 * RADIUS);
            g.setColor(Color.WHITE);
            g.drawString(String.valueOf(i), x - 5, y + 5);
        }

        // 绘制边
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (graph[i][j] != 0) {
                    int x1 = (i % 4 + 1) * WIDTH / 5;
                    int y1 = (i / 4 + 1) * HEIGHT / 3;
                    int x2 = (j % 4 + 1) * WIDTH / 5;
                    int y2 = (j / 4 + 1) * HEIGHT / 3;
                    g.setColor(minTree.contains(i) && minTree.contains(j) ? Color.RED : Color.BLACK);
                    g.drawLine(x1, y1, x2, y2);
                }
            }
        }
    }

    public static void main(String[] args) {
        int[][] graph = {
            {0, 2, 0, 6, 0},
            {2, 0, 3, 8, 5},
            {0, 3, 0, 0, 7},
            {6, 8, 0, 0, 9},
            {0, 5, 7, 9, 0}
        };

        JFrame frame = new JFrame("Prim Visualization");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new PrimVisualization(graph));
        frame.pack();
        frame.setVisible(true);
    }
}

7.2案例2: 最小生成树的路径规划

import java.util.*;

public class PrimPathPlanning {
    public static void main(String[] args) {
        int[][] graph = {
            {0, 2, 0, 6, 0},
            {2, 0, 3, 8, 5},
            {0, 3, 0, 0, 7},
            {6, 8, 0, 0, 9},
            {0, 5, 7, 9, 0}
        };

        int start = 0;
        int end = 4;

        List<Integer> path = primPath(graph, start, end);

        System.out.println("最小生成树路径:" + path);
    }

    public static List<Integer> primPath(int[][] graph, int start, int end) {
        int n = graph.length;
        int[] parent = new int[n];
        int[] key = new int[n];
        boolean[] inTree = new boolean[n];

        Arrays.fill(key, Integer.MAX_VALUE);

        key[start] = 0;
        parent[start] = -1;

        for (int i = 0; i < n - 1; i++) {
            int u = findMinKey(key, inTree);
            inTree[u] = true;

            for (int v = 0; v < n; v++) {
                if (graph[u][v] != 0 && !inTree[v] && graph[u][v] < key[v]) {
                    parent[v] = u;
                    key[v] = graph[u][v];
                }
            }
        }

        List<Integer> path = new ArrayList<>();
        int current = end;

        while (current != -1) {
            path.add(current);
            current = parent[current];
        }

        Collections.reverse(path);
        return path;
    }

    public static int findMinKey(int[] key, boolean[] inTree) {
        int minKey = Integer.MAX_VALUE;
        int minKeyIndex = -1;

        for (int i = 0; i < key.length; i++) {
            if (!inTree[i] && key[i] < minKey) {
                minKey = key[i];
                minKeyIndex = i;
            }
        }

        return minKeyIndex;
    }
}

你可能感兴趣的:(Java手写源码合集,java,算法,开发语言)