最小生成树

Prim算法

在这里插入图片描述
tree是一个List,用来存放已加入生成树的节点;nodes是一个一维数组,包含了所有节点;e是一个二维数组,用来表示图邻接矩阵。
(1)初始时,选取一个节点作为起点放入tree中。
(2)遍历tree中的所有节点,找出距离tree中节点最近的其他节点,记录下当前邻接边的起始节点和终止节点。
(3)将终止节点加入tree中,并记录该终止节点的父节点为起始节点。
(4)重复步骤(2)和(3)直到tree包含了所有节点。
(5)打印出最小生成树。

import java.util.*;

public class Main {
	public static void main(String[] args) {
		String[] names = {"A","B","C","D","E","F"};
		
		Node[] nodes = new Node[names.length];
		for(int i=0;i<names.length;i++) {
			nodes[i] = new Node(names[i],i);
		}
		
		int inf = Integer.MAX_VALUE;
		int[][] e ={{inf,6,1,5,inf,inf},
					{6,inf,5,inf,3,inf},
					{1,5,inf,5,6,4},
					{5,inf,5,inf,inf,2},
					{inf,3,6,inf,inf,6},
					{inf,inf,4,2,6,inf}};

		int begin = 0;
		int end = 0;
		List<Node> tree = new ArrayList<Node>();
		tree.add(nodes[0]);
		while(tree.size()<nodes.length) {
			int min = inf;
			for(Node node:tree) {
				for(int i=0;i<nodes.length;i++) {
					if(e[node.num][i]<min && !tree.contains(nodes[i])) {
						min = e[node.num][i];
						begin = node.num;
						end = i;
					}
				}
			}
			tree.add(nodes[end]);
			nodes[end].parent = nodes[begin];
		}
		for(Node node:tree) {
			if(node.parent!=null) {
				System.out.print("("+node.parent.name+"-"+node.name+")"+" ");
			}
			
		}
		
	}
	
}


public class Node {
	public Object name; 	//节点名称
	public int num;			//节点数字代号
	public Node parent;	//节点的父节点
	public Node(Object name,int num) {
		this(name,num,null);
	}
	public Node(Object name,int num,Node parent) {
		this.name=name;
		this.num = num;
		this.parent = parent;
	}
}

Kruskal算法

在这里插入图片描述
(1)初始时将所有的节点当成一个独立的树,这些树组成trees。
(2)在所有的边中选出最短的边,并且该边的两个节点不在同一棵树中,记录该边的两个节点。
(3)将该边所在的两棵树合并,并打印出该边。
(4)重复步骤(2)和(3),直到仅剩下一棵树。
关于选出最短边,可以先对所有边进行排序再挑选,以此优化算法。

import java.util.*;

public class Main {
	public static void main(String[] args) {
		String[] names = {"A","B","C","D","E","F"};
		
		Node[] nodes = new Node[names.length];
		
		
		int inf = Integer.MAX_VALUE;
		int[][] e ={{inf,6,1,5,inf,inf},
					{6,inf,5,inf,3,inf},
					{1,5,inf,5,6,4},
					{5,inf,5,inf,inf,2},
					{inf,3,6,inf,inf,6},
					{inf,inf,4,2,6,inf}};

		int begin = 0;
		int end = 0;
		ArrayList<ArrayList<Node>> trees = new ArrayList<ArrayList<Node>>();
		for(int i=0;i<nodes.length;i++) {
			nodes[i] = new Node(names[i],i);
			ArrayList<Node> list = new ArrayList<Node>();
			list.add(nodes[i]);
			trees.add(list);
		}

		while(trees.size()>1) {
			int min = inf;
			for(int i=0;i<nodes.length;i++) {
				for(int j=0;j<nodes.length;j++) {
					if(e[i][j]<min && findTree(trees,nodes[i])!=findTree(trees,nodes[j])) {
						min = e[i][j];
						begin = i;
						end = j;
					}
				}
			}
			
			int beginTree = findTree(trees,nodes[begin]);
			int endTree = findTree(trees,nodes[end]);
			trees.get(beginTree).addAll(trees.get(endTree));
			trees.remove(endTree);
			System.out.print("("+nodes[begin].name+"-"+nodes[end].name+")"+" ");
		}
		
		
		
	}
	
	public static int findTree(ArrayList<ArrayList<Node>> trees,Node node) {
		for(int i=0;i<trees.size();i++) {
			if(trees.get(i).contains(node)) {
				return i;
			}
		}
		return -1;
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值