算法代码

C#代码

using System;

namespace Prim
{
class Program
{
static void Main(string[] args)
{
int numberOfVertexes = 9,
infinity = int.MaxValue; int[][] graph = new int[][] {
new int[]{0, 10, infinity, infinity, infinity, 11, infinity, infinity, infinity },
new int[]{ 10, 0, 18, infinity, infinity, infinity, 16, infinity, 12 },
new int[]{ infinity, 18, 0, 22, infinity, infinity, infinity, infinity, 8 },
new int[]{ infinity, infinity, 22, 0, 20, infinity, 24, 16, 21 },
new int[]{ infinity, infinity, infinity, 20, 0, 26, infinity, 7, infinity },
new int[]{ 11, infinity, infinity, infinity, 26, 0, 17, infinity, infinity },
new int[]{ infinity, 16, infinity, 24, infinity, 17, 0, 19, infinity },
new int[]{ infinity, infinity, infinity, 16, 7, infinity, 19, 0, infinity },
new int[]{ infinity, 12, 8, 21, infinity, infinity, infinity, infinity, 0 },
}; //Prim(graph, numberOfVertexes);
PrimSimplified(graph, numberOfVertexes);
} static void Prim(int[][] graph, int numberOfVertexes)
{
bool debug = true; int[] adjVex = new int[numberOfVertexes], // 邻接顶点数组:搜索边的最小权值过程中各边的起点坐标
lowCost = new int[numberOfVertexes]; // 各边权值数组:搜索边的最小权值过程中各边的权值,数组下标为边的终点。 for (int i = 0; i < numberOfVertexes; i++) // 从图G的下标为0的顶点开始搜索。(也是图G的最小生成树的顶点集合)。
{
adjVex[i] = 0;
} for (int i = 0; i < numberOfVertexes; i++) // 初始从下标为0的顶点开始到下标为i的顶点的边的权值去搜索。找lowCost中权值最小的下标i。
{
lowCost[i] = graph[0][i];
} int k = 0; // 初始假定权值最小的边的终点的下标为k。 for (int i = 1; i < numberOfVertexes; i++)
{
if (debug)
{
Console.WriteLine($"Loop {i}");
Console.Write("lowCost: ");
PrintArray(lowCost);
Console.Write(" adjVex: ");
PrintArray(adjVex);
Console.WriteLine();
} int minimumWeight = int.MaxValue; // 搜索过程中发现到的最小的权值。初始设置为最大的整数值以示两点间无边。 for (int j = 1; j < numberOfVertexes; j++)
{
if (lowCost[j] != 0 && lowCost[j] < minimumWeight) // lowCost中0表示该点已经搜索过了。lowCost[j] < minimumWeight即发现目前最小权值。
{
minimumWeight = lowCost[j]; // 发现目前最小权值。
k = j; // 目前最小权值的边的终点下标。
}
} if (!debug)
{
Console.WriteLine($"({adjVex[k]}, {k})"); // 输出边
} adjVex[i] = k; // 此时找到的k值即是权值最小的边的终点。将V[k]放入集合U。(这步可省略,因lowCost[j]已被标为“无需搜索”了)。
lowCost[k] = 0; // 0表示该点已经搜索过了,已不需要再被搜索了。 for (int j = 1; j < numberOfVertexes; j++) // 转到以V[k]为开始顶点的边,去与前面u为起始顶点到V[i]为终止顶点的边的权值去比较。
{
if (lowCost[j] != 0 && graph[k][j] < lowCost[j]) // lowCost中0表示该点已经搜索过了。graph[k][j] < lowCost[j]即发现更小权值。
{
lowCost[j] = graph[k][j]; // 更新权值;索引j即终点下标。
adjVex[j] = k; // 下次寻找权值小的边时,从k为下标的顶点为起点。
}
} if (debug)
{
Console.Write("lowCost: ");
PrintArray(lowCost);
Console.Write(" adjVex: ");
PrintArray(adjVex);
Console.WriteLine();
}
}
} static void PrimSimplified(int[][] graph, int numberOfVertexes)
{
int[] adjVex = new int[numberOfVertexes], // 邻接顶点数组:搜索边的最小权值过程中各边的起点坐标
lowCost = new int[numberOfVertexes]; // 各边权值数组:搜索边的最小权值过程中各边的权值,数组下标为边的终点。 for (int i = 0; i < numberOfVertexes; i++)
{
adjVex[i] = 0; // 从图G的下标为0的顶点开始搜索。(也是图G的最小生成树的顶点集合)。
lowCost[i] = graph[0][i]; // 初始从下标为0的顶点开始到下标为i的顶点的边的权值去搜索。找lowCost中权值最小的下标i。
} int k = 0; // 初始假定权值最小的边的终点的下标为k。 for (int i = 1; i < numberOfVertexes; i++)
{
int minimumWeight = int.MaxValue; // 搜索过程中发现到的最小的权值。初始设置为最大的整数值以示两点间无边。 for (int j = 1; j < numberOfVertexes; j++)
{
if (lowCost[j] != 0 && lowCost[j] < minimumWeight) // lowCost中0表示该点已经搜索过了。lowCost[j] < minimumWeight即发现目前最小权值。
{
minimumWeight = lowCost[j]; // 发现目前最小权值。
k = j; // 目前最小权值的边的终点下标。
}
} Console.WriteLine($"({adjVex[k]}, {k})"); // 输出边 lowCost[k] = 0; // 0表示该点已经搜索过了,已不需要再被搜索了。 for (int j = 1; j < numberOfVertexes; j++) // 转到以V[k]为开始顶点的边,去与前面u为起始顶点到V[i]为终止顶点的边的权值去比较。
{
if (lowCost[j] != 0 && graph[k][j] < lowCost[j]) // lowCost中0表示该点已经搜索过了。graph[k][j] < lowCost[j]即发现更小权值。
{
lowCost[j] = graph[k][j]; // 更新权值;索引j即终点下标。
adjVex[j] = k; // 下次寻找权值小的边时,从k为下标的顶点为起点。
}
}
}
} static void PrintArray(int[] array)
{
Console.Write("[ ");
for (int i = 0; i < array.Length - 1; i++) // 输出数组的前面n-1个
{
Console.Write($"{ToInfinity(array[i])}, ");
}
if (array.Length > 0) // 输出数组的最后1个
{
int n = array.Length - 1;
Console.Write($"{ToInfinity(array[n])}");
}
Console.WriteLine(" ]");
} static string ToInfinity(int i) => i == int.MaxValue ? "∞" : i.ToString();
}
}

TypeScript代码

function prim(graph: number[][], numberOfVertexes: number) {
let debug: boolean = true; let adjVex: number[] = [], // 邻接顶点数组:搜索边的最小权值过程中各边的起点坐标
lowCost = []; // 各边权值数组:搜索边的最小权值过程中各边的权值,数组下标为边的终点。 for (let i = 0; i < numberOfVertexes; i++) // 从图G的下标为0的顶点开始搜索。(也是图G的最小生成树的顶点集合)。
{
adjVex[i] = 0;
} for (let i = 0; i < numberOfVertexes; i++) // 初始从下标为0的顶点开始到下标为i的顶点的边的权值去搜索。找lowCost中权值最小的下标i。
{
lowCost[i] = graph[0][i];
} let k: number = 0; // 初始假定权值最小的边的终点的下标为k。 for (let i = 1; i < numberOfVertexes; i++) {
if (debug) {
console.log(`Loop ${i}`);
console.log(`lowCost: ${printArray(lowCost)}`);
console.log(` adjVex: ${printArray(adjVex)}`);
} // 搜索过程中发现到的最小的权值。初始设置为最大的整数值以示两点间无边。
let minimumWeight: number = Number.MAX_VALUE; for (let j = 1; j < numberOfVertexes; j++) {
// lowCost中0表示该点已经搜索过了。lowCost[j] < minimumWeight即发现目前最小权值。
if (lowCost[j] != 0 && lowCost[j] < minimumWeight)
{
minimumWeight = lowCost[j]; // 发现目前最小权值。
k = j; // 目前最小权值的边的终点下标。
}
} if (!debug) {
console.log(`(${adjVex[k]}, ${k})`);// 输出边
} adjVex[i] = k; // 此时找到的k值即是权值最小的边的终点。将V[k]放入集合U。(这步可省略,因lowCost[j]已被标为“无需搜索”了)。
lowCost[k] = 0; // 0表示该点已经搜索过了,已不需要再被搜索了。 // 转到以V[k]为开始顶点的边,去与前面u为起始顶点到V[i]为终止顶点的边的权值去比较。
for (let j = 1; j < numberOfVertexes; j++)
{
// lowCost中0表示该点已经搜索过了。graph[k][j] < lowCost[j]即发现更小权值。
if (lowCost[j] != 0 && graph[k][j] < lowCost[j])
{
lowCost[j] = graph[k][j]; // 更新权值;索引j即终点下标。
adjVex[j] = k; // 下次寻找权值小的边时,从k为下标的顶点为起点。
}
} if (debug) {
console.log(`lowCost: ${printArray(lowCost)}`);
console.log(` adjVex: ${printArray(adjVex)}`);
console.log('');
}
}
} function primSimplified(graph: number[][], numberOfVertexes: number) {
let adjVex: number[] = [], // 邻接顶点数组:搜索边的最小权值过程中各边的起点坐标
lowCost = []; // 各边权值数组:搜索边的最小权值过程中各边的权值,数组下标为边的终点。 for (let i = 0; i < numberOfVertexes; i++) {
adjVex[i] = 0; // 从图G的下标为0的顶点开始搜索。(也是图G的最小生成树的顶点集合)。
lowCost[i] = graph[0][i]; // 初始从下标为0的顶点开始到下标为i的顶点的边的权值去搜索。找lowCost中权值最小的下标i。
} let k: number = 0; // 初始假定权值最小的边的终点的下标为k。 for (let i = 1; i < numberOfVertexes; i++) {
// 搜索过程中发现到的最小的权值。初始设置为最大的整数值以示两点间无边。
let minimumWeight: number = Number.MAX_VALUE; for (let j = 1; j < numberOfVertexes; j++) {
// lowCost中0表示该点已经搜索过了。lowCost[j] < minimumWeight即发现目前最小权值。
if (lowCost[j] != 0 && lowCost[j] < minimumWeight)
{
minimumWeight = lowCost[j]; // 发现目前最小权值。
k = j; // 目前最小权值的边的终点下标。
}
} console.log(`(${adjVex[k]}, ${k})`); // 输出边 lowCost[k] = 0; // 0表示该点已经搜索过了,已不需要再被搜索了。 // 转到以V[k]为开始顶点的边,去与前面u为起始顶点到V[i]为终止顶点的边的权值去比较。
for (let j = 1; j < numberOfVertexes; j++)
{
// lowCost中0表示该点已经搜索过了。graph[k][j] < lowCost[j]即发现更小权值。
if (lowCost[j] != 0 && graph[k][j] < lowCost[j])
{
lowCost[j] = graph[k][j]; // 更新权值;索引j即终点下标。
adjVex[j] = k; // 下次寻找权值小的边时,从k为下标的顶点为起点。
}
}
}
} function printArray(array: number[]): string {
let str: string[] = [];
str.push("[ ");
for (let i = 0; i < array.length - 1; i++) // 输出数组的前面n-1个
{
str.push(`${toInfinity(array[i])}, `)
}
if (array.length > 0) // 输出数组的最后1个
{
let n: number = array.length - 1;
str.push(`${toInfinity(array[n])}`);
}
str.push(" ]");
return str.join("");
} function toInfinity(i: number) {
return i == Number.MAX_VALUE ? "∞" : i.toString();
} function Main() {
let numberOfVertexes: number = 9,
infinity = Number.MAX_VALUE; let graph: number[][] = [
[0, 10, infinity, infinity, infinity, 11, infinity, infinity, infinity],
[10, 0, 18, infinity, infinity, infinity, 16, infinity, 12],
[infinity, 18, 0, 22, infinity, infinity, infinity, infinity, 8],
[infinity, infinity, 22, 0, 20, infinity, 24, 16, 21],
[infinity, infinity, infinity, 20, 0, 26, infinity, 7, infinity],
[11, infinity, infinity, infinity, 26, 0, 17, infinity, infinity],
[infinity, 16, infinity, 24, infinity, 17, 0, 19, infinity],
[infinity, infinity, infinity, 16, 7, infinity, 19, 0, infinity],
[infinity, 12, 8, 21, infinity, infinity, infinity, infinity, 0],
]; prim(graph, numberOfVertexes);
primSimplified(graph, numberOfVertexes);
} Main();

参考资料:

《大话数据结构》 - 程杰 著 - 清华大学出版社 第247页

普里姆算法(Prim)邻接矩阵法的更多相关文章

  1. 最小生成树练习3(普里姆算法Prim)

    风萧萧兮易水寒,壮士要去敲代码.本女子开学后再敲了.. poj1258 Agri-Net(最小生成树)水题. #include<cstdio> #include<cstring> ...

  2. 普里姆算法(Prim)

    概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图(带权图)里搜索最小生成树.即此算法搜索到的边(Edge)子集所构成的树中,不但包括了连通图里的所有顶点(Vertex)且其所有边的权 ...

  3. 普里姆(Prim)算法

    概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图(即"带权图")里搜索最小生成树.即此算法搜索到的边(Edge)子集所构成的树中,不但包括了连通图里的所有顶点(V ...

  4. 查找最小生成树:普里姆算法算法(Prim)算法

    一.算法介绍 普里姆算法(Prim's algorithm),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之 ...

  5. HDU 1879 继续畅通工程 (Prim(普里姆算法)+Kruskal(克鲁斯卡尔))

    继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  6. hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)

    还是畅通工程 Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  7. 最小生成树---普里姆算法(Prim算法)和克鲁斯卡尔算法(Kruskal算法)

    普里姆算法(Prim算法) #include<bits/stdc++.h> using namespace std; #define MAXVEX 100 #define INF 6553 ...

  8. ACM第四站————最小生成树(普里姆算法)

    对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成 ...

  9. 图->连通性->最小生成树(普里姆算法)

    文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可 ...

随机推荐

  1. 《逆向工程核心原理》Windows消息钩取

    DLL注入--使用SetWindowsHookEx函数实现消息钩取 MSDN: SetWindowsHookEx Function The SetWindowsHookEx function inst ...

  2. 创建ortools的Dockerfile

    技术背景 基于已有的Docker容器镜像,去创建一个本地的镜像,有两种方法:一种是在之前的博客中提到过的,使用docker commit的方案,也就是先进去基础系统镜像内部完成所需的修改,然后comm ...

  3. MyBatis笔记(六)

    1. 动态SQL 1.1 介绍 概念:**动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.* 官网描述: MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其 ...

  4. 【算法笔记】二分图与KM算法(当你试图只看蓝书学算法

    前言 呜,好久没写博客了,DDL 也有好多,一不留神就轮到我了呜. 看了一眼其它同学写的博客,什么数模啊,什么 CTF 啊,什么 Python 爬虫啊,感觉自己真是越来越菜了呜. 然后在我一愁莫展之际 ...

  5. java中的|=符号

    今天看mybaits源码的时候,发现了这个特殊的符号用法,|=. for (ParameterMapping pm : boundSql.getParameterMappings()) { Strin ...

  6. Day16_91_通过反射机制获取父类和父接口

    通过反射机制获取父类和父接口 * 代码: import java.net.InterfaceAddress; public class ReflectTest14 { public static vo ...

  7. Day05_19_方法回顾

    方法回顾 * 静态方法 和 非静态方法 1.静态方法属于类所有,类实例化前即可使用: 2.非静态方法可以访问类中的任何成员,静态方法只能访问类中的静态成员: 3.因为静态方法会在类加载的时候就进行初始 ...

  8. kubespray续签k8s证书

    查看证书过期时期 [root@node1 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep ' Not ...

  9. shopify 学习链接整理

    shopify shopify packagist https://help.shopify.com/zh-CN/manual/apps/apps-by-shopify/script-editor/s ...

  10. wordpress current_user_can 判断角色

    current_user_can 使用说明: current_user_can( $capability, $args ); $capability参数是必须的,是指给予什么样的能力,或者说给他可以做 ...