单源最短路径问题Java代码实现

**

The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative.

**
import java.io.IOException;
import java.util.Scanner;

public class Bellman_Ford {

public class ENode2 {
	int weight;
	int ivex; // 该边所指向的顶点的位置
	ENode2 nextEdge; // 指向下一条弧的指针
}

// 邻接表中表的顶点
private class VNode2 {
	int d;
	VNode2 pre;
	char data; // 顶点信息
	ENode2 firstEdge; // 指向第一条依附该顶点的弧
};

private VNode2[] mVexs; // 顶点数组

/*
 * 创建图(自己输入数据)
 */
public Bellman_Ford() {

	// 输入"顶点数"和"边数"
	System.out.printf("input vertex number: ");
	int vlen = readInt();
	System.out.printf("input edge number: ");
	int elen = readInt();
	if (vlen < 1 || elen < 1 || (elen > (vlen * (vlen - 1)))) {
		System.out.printf("input error: invalid parameters!\n");
		return;
	}

	// 初始化"顶点"
	mVexs = new VNode2[vlen];
	for (int i = 0; i < mVexs.length; i++) {
		System.out.printf("vertex(%d): ", i);
		mVexs[i] = new VNode2();
		mVexs[i].data = readChar();
		mVexs[i].firstEdge = null;
	}

	// 初始化"边"
	// mMatrix = new int[vlen][vlen];
	for (int i = 0; i < elen; i++) {
		// 读取边的起始顶点和结束顶点
		System.out.printf("edge(%d):", i);
		char c1 = readChar();
		char c2 = readChar();
		int w = readInt();
		int p1 = getPosition(c1);
		int p2 = getPosition(c2);
		// 初始化node1
		ENode2 node1 = new ENode2();
		node1.ivex = p2;
		node1.weight = w;
		// 将node1链接到"p1所在链表的末尾"
		if (mVexs[p1].firstEdge == null)
			mVexs[p1].firstEdge = node1;
		else
			linkLast(mVexs[p1].firstEdge, node1);
	}
}

public Bellman_Ford(char[] vexs, char[][] edges, int[] weigh) {

	// 初始化"顶点数"和"边数"
	int vlen = vexs.length;
	int elen = edges.length;

	// 初始化"顶点"
	mVexs = new VNode2[vlen];
	for (int i = 0; i < mVexs.length; i++) {
		mVexs[i] = new VNode2();
		mVexs[i].data = vexs[i];
		mVexs[i].firstEdge = null;
	}

	// 初始化"边"
	for (int i = 0; i < elen; i++) {
		// 读取边的起始顶点和结束顶点
		char c1 = edges[i][0];
		char c2 = edges[i][1];
		// 读取边的起始顶点和结束顶点
		int p1 = getPosition(edges[i][0]);
		int p2 = getPosition(edges[i][1]);

		// 初始化node1
		ENode2 node1 = new ENode2();
		node1.ivex = p2;
		// 将node1链接到"p1所在链表的末尾"
		if (mVexs[p1].firstEdge == null)
			mVexs[p1].firstEdge = node1;
		else
			linkLast(mVexs[p1].firstEdge, node1);
		node1.weight = weigh[i];
	}
}

public void Initialize() {
	for (int i = 0; i < mVexs.length; i++) {
		mVexs[i].d = Integer.MAX_VALUE;
		// mVexs[i].pre = null;
	}
	mVexs[0].d = 0;
}


public boolean Bellman_Ford() {
	Initialize();// 初始化
	// System.out.println("输出最短路径:");
	// System.out.printf("%c",mVexs[0].data );
	for (int i = 0; i < mVexs.length; i++) {
		for (int j = 0; j < mVexs.length; j++) {
			ENode2 node = mVexs[j].firstEdge;
			while (node != null) {
				if (mVexs[node.ivex].d > mVexs[j].d + node.weight) {//进行relax操作
					mVexs[node.ivex].d = mVexs[j].d + node.weight;
				}
				// Relax(mVexs[i], mVexs[node.ivex]);
				node = node.nextEdge;
			}
		}
	}
	for (int k = 0; k < mVexs.length; k++) {
		ENode2 node = mVexs[k].firstEdge;
		while (node != null) {
			if (mVexs[(node.ivex)].d > mVexs[k].d + node.weight) {
				return false;
			}
			node = node.nextEdge;
		}
	}
	
	return true;
	
}

//输出源点s到每个节点的最短路径
public void Distance() {
	System.out.print("输出源点s到每个节点的最短路径:");
	for (int i = 0; i < mVexs.length; i++) {
		System.out.print(mVexs[i].data+":"+mVexs[i].d+"   ");

	}
	System.out.println();
}

//输出最短路径
public void SmallPath_output() {
	boolean temp = Bellman_Ford();
	if (temp == false) {
		System.out.println("存在权重为负值的环路!");

	} else {
		System.out.println("输出最短路径为:");
		for (int i = 0; i < mVexs.length; i++) {
			ENode2 node = mVexs[i].firstEdge;
			while (node != null) {
				if (mVexs[(node.ivex)].d == mVexs[i].d + node.weight&&node.ivex==0) {
					System.out.println("指向源节点的不输出!");
				}
				else if(mVexs[(node.ivex)].d == mVexs[i].d + node.weight){
					System.out.println(mVexs[i].data + "-->" + mVexs[(node.ivex)].data + " " + node.weight);
				}
				node = node.nextEdge;
			}
		}

	}

}


//输出每条边的权重
public void PrintWeight() {
	for (int i = 0; i < mVexs.length; i++) {
		ENode2 node = mVexs[i].firstEdge;
		while (node != null) {
			System.out.println(mVexs[i].data+"-->"+mVexs[node.ivex].data+" "+node.weight);
			node = node.nextEdge;
		}
	}
}

/*
 * 将node节点链接到list的最后
 */
private void linkLast(ENode2 list, ENode2 node) {
	ENode2 p = list;

	while (p.nextEdge != null)
		p = p.nextEdge;
	p.nextEdge = node;
}

/*
 * 返回ch位置
 */
private int getPosition(char ch) {
	for (int i = 0; i < mVexs.length; i++)
		if (mVexs[i].data == ch)
			return i;
	return -1;
}

/*
 * 读取一个输入字符
 */
private char readChar() {
	char ch = '0';

	do {
		try {
			ch = (char) System.in.read();
		} catch (IOException e) {
			e.printStackTrace();
		}
	} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));

	return ch;
}

/*
 * 读取一个输入字符
 */
private int readInt() {
	Scanner scanner = new Scanner(System.in);
	return scanner.nextInt();
}

/*
 * 打印矩阵队列图
 */
public void Graph_Print() {
	System.out.println("List Graph:");
	for (int i = 0; i < mVexs.length; i++) {
		System.out.print( i+"("+ mVexs[i].data+"):");
		ENode2 node = mVexs[i].firstEdge;
		while (node != null) {
			System.out.print( node.ivex+"("+ mVexs[i].data+"-"+node.weight+"->"+ mVexs[node.ivex].data+")");
			System.out.printf("\t");
			node = node.nextEdge;
		}
		System.out.printf("\n");
	}
}

public static void main(String[] args) {

	int[] weight = { 6, 7, 5, 8, -4, -2, -3, 9, 2, 7 };
	char[] vexs = { 'A', 'B', 'C', 'D', 'E' };
	char[][] edges = new char[][] { { 'A', 'B' }, { 'A', 'D' }, { 'B', 'C' }, { 'B', 'D' }, { 'B', 'E' },
			{ 'C', 'B' }, { 'D', 'C' }, { 'D', 'E' }, { 'E', 'A' }, { 'E', 'C' }, };

	Bellman_Ford bf = new Bellman_Ford(vexs, edges, weight);
	bf.PrintWeight();
	bf.Graph_Print();
	//bf.Bellman_Ford();
	System.out.println(bf.Bellman_Ford());
	bf.Distance();
	bf.SmallPath_output();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值