StackX
package dfs;
/**
* @author CSDN@日星月云
* @date 2022/10/26 19:03
*/
public class StackX {
private final int SIZE = 20;
private int[] st;
private int top;
public StackX() {// constructor
st = new int[SIZE];
top = -1;// make array
}
public void push(int j) { // put item on stack
st[++top] = j;
}
public int pop() {// take item off stack
return st[top--];
}
public int peek() {// peek at top of stack
return st[top];
}
public boolean isEmpty() { // true if nothing on stack
return (top == -1);
}
//测试StackX
public static void main(String[] args) {
StackX stackX=new StackX();
System.out.println(stackX.isEmpty());
stackX.push(1);
stackX.push(2);
stackX.push(3);
stackX.pop();
int peek = stackX.peek();
System.out.println(peek);
stackX.pop();
stackX.pop();
System.out.println(stackX.isEmpty());
}
} // end class Stackx
QueueX
package bfs;
/**
* @author CSDN@日星月云
* @date 2022/10/26 19:10
*/
public class QueueX {
private final int SIZE = 20;
private int[] queArray;
private int front;
private int rear;
public QueueX() {// constructor
queArray = new int[SIZE];
front = 0;
rear = -1;
}
public void insert(int j) {// put item at rear of queue
if (rear == SIZE - 1)
rear = -1;
queArray[++rear] = j;
}
public int remove() {// take item from front of queue
int temp = queArray[front++];
if (front == SIZE)
front = 0;
return temp;
}
public boolean isEmpty() {// true if queue is empty
return (rear + 1 == front || (front + SIZE - 1 == rear));
}
//测试Queue
public static void main(String[] args) {
QueueX queueX =new QueueX();
System.out.println(queueX.isEmpty());
queueX.insert(1);
queueX.insert(2);
queueX.insert(3);
int remove = queueX.remove();
System.out.println(remove);
queueX.remove();
queueX.remove();
System.out.println(queueX.isEmpty());
}
} // end class QueueX
dfs
DFSApp
package dfs;
/**
* @author CSDN@日星月云
* @date 2022/10/26 18:37
* bfs
* 深度优先搜索
* 规则1如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
* 规则2当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
* 规则3如果不能执行规则1和规则2,就完成了整个搜索过程。
*/
class Vertex {
public char label;// label (e.g. 'A')
public boolean wasVisited;
public Vertex(char lab){// constructor
label = lab;
wasVisited = false;
}
}
class Graph {
private final int MAX_VERTS = 20;
private Vertex vertexList[]; // array of vertices
private int adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
private StackX theStack;
//------------------------------------------------------------
public Graph() { // constructor
vertexList = new Vertex[MAX_VERTS];// adjacency matrix
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int j = 0; j < MAX_VERTS; j++)// set adjacency
for (int k = 0; k < MAX_VERTS; k++)//matrix to 0
adjMat[j][k] = 0;
theStack = new StackX();
}// end constructor
//------------------------------------------------------------
public void addVertex(char lab) {// argument is label
vertexList[nVerts++] = new Vertex(lab);
}
//------------------------------------------------------------
public void addEdge(int start, int end) {
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
//------------------------------------------------------------
/**
* 深度优先搜索的关键在于能够找到与某一顶点邻接且没有访问过的顶点。如何做呢?邻接矩阵
* 是关键。找到指定顶点所在的行,从第一列开始向后寻找值为1的列:列号是邻接顶点的号码。检
* 查这个顶点是否未访问过,如果是这样,那么这就是要访问的下一个顶点。如果该行没有顶点既等
* 于1 (邻接)且又是未访问的,那么与指定点相邻接的顶点就全部访问过了。这个过程在
* getAdjUnvisitedVertex ()方法中实现:
*/
// returns an unvisited vertex adjacent to v
public int getAdjUnvisitedVertex(int v) {
for (int j = 0; j < nVerts; j++)
if (adjMat[v][j] == 1 && vertexList[j].wasVisited == false)
return j;// return first such vertex
return -1;// no such vertices
} // end getAdjUnvisitedVertex()
/**
* 现在开始考察Graph类中的dfs()方法,这个方法实际执行了深度优先搜索。下面会看到这段代
* 码如何包含了前面提出的三条规则。它循环执行,直到栈为空。每次循环中,它做四件书:
* 1.用peek()方法检查栈顶的顶点。
* 2.试图找到这个顶点还未访问的邻接点。
* 3.如果没有找到,出栈。
* 4.如果找到这样的顶点,访问这个顶点,并把它放入栈。
* 5.下面是dfs()方法的代码:
*/
public void dfs() { // depth-first search
// Stack<Integer> theStack = new Stack<>();//java.util.Stack
// begin at vertex 0
vertexList[0].wasVisited = true;// mark it
displayVertex(0);//display it
theStack.push(0);// push it
while (!theStack.isEmpty()) {// until stack empty,
// get an unvisited vertex adjacent to stack top
int v = getAdjUnvisitedVertex(theStack.peek());
if (v == -1)// if no such vertex,
theStack.pop();//pop a new one
else {// if it exists,
vertexList[v].wasVisited = true; // mark it
displayVertex(v); // display it
theStack.push(v);// push it
}
} // end while
// stack is empty, so we're done
for (int j = 0; j < nVerts; j++)// reset flags
vertexList[j].wasVisited = false;
}// end dfs
/**
* 在dfs()方法的最后,重置了所有wasVisited标记位,这样就可以在稍后继续使用dfs()方法。栈
* 此时已为空,所以不需要重置。
*/
}// end class Graph
class DFSApp{
/**
* 现在Graph类已经有了需要的所有片段.下面是创建图对象的代码,并在图中加入一些顶点和
* 边,然后执行深度优先搜索
*/
public static void main(String[] args) {
Graph theGraph = new Graph();
theGraph.addVertex('A');//0 (start for dfs)
theGraph.addVertex('B');//1
theGraph.addVertex('C');//2
theGraph.addVertex('D');//3
theGraph.addVertex('E');//4
theGraph.addEdge(0, 1);// AB
theGraph.addEdge(1, 2);// BC
theGraph.addEdge(0, 3);// AD
theGraph.addEdge(3, 4);// DE
/*
A--B--C
|
D--E
*/
System.out.print("Visits:");
theGraph.dfs(); // depth-first search
System.out.println();//Visits:ABCDE
}
}
bfs
BFSApp
package bfs;
/**
* @author CSDN@日星月云
* @date 2022/10/26 18:37
* bfs
* 广度优先搜索
* 规则1访问下一个未来访问的邻接点(如果存在),这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。
* 规则2如果因为已经没有未访问顶点而不能执行规则1,那么从队列头取一个顶点(如果存在),并使其成为当前顶点。
* 规则3如果因为队列为空而不能执行规则2,则搜索结束。
*/
class Vertex {
public char label;// label (e.g. 'A')
public boolean wasVisited;
public Vertex(char lab){// constructor
label = lab;
wasVisited = false;
}
}
class Graph {
private final int MAX_VERTS = 20;
private Vertex vertexList[]; // array of vertices
private int adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
private QueueX theQueueX;
//------------------------------------------------------------
public Graph() { // constructor
vertexList = new Vertex[MAX_VERTS];// adjacency matrix
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int j = 0; j < MAX_VERTS; j++)// set adjacency
for (int k = 0; k < MAX_VERTS; k++)//matrix to 0
adjMat[j][k] = 0;
theQueueX = new QueueX();
}// end constructor
//------------------------------------------------------------
public void addVertex(char lab) {// argument is label
vertexList[nVerts++] = new Vertex(lab);
}
//------------------------------------------------------------
public void addEdge(int start, int end) {
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
//------------------------------------------------------------
// returns an unvisited vertex adjacent to v
public int getAdjUnvisitedVertex(int v) {
for (int j = 0; j < nVerts; j++)
if (adjMat[v][j] == 1 && vertexList[j].wasVisited == false)
return j;// return first such vertex
return -1;// no such vertices
} // end getAdjUnvisitedVertex()
public void bfs() {// breadth-first search
// Queue<Integer> theQueue=new ArrayDeque<>();//java.util.Queue
// begin at vertex 0
vertexList[0].wasVisited = true; // mark it
displayVertex(0);// display it
theQueueX.insert(0); // insert at tail
int v2;
while (!theQueueX.isEmpty()) {// until queue empty,
int v1 = theQueueX.remove();// remove vertex at head
// until it has no unvisited neighbors
while ((v2 = getAdjUnvisitedVertex(v1)) != -1) {// get one,
vertexList[v2].wasVisited = true;// mark it
displayVertex(v2);// display it
theQueueX.insert(v2);// insert it
} // end while
}// end while(queue not empty)
// queue is empty, so we're done
for (int j = 0; j < nVerts; j++) {
vertexList[j].wasVisited = false; // reset flags
}
}// end bfs()
}// end class Graph
public class BFSApp{
//测试 bfs
public static void main(String[] args) {
Graph theGraph = new Graph();
theGraph.addVertex('A');//0 (start for dfs)
theGraph.addVertex('B');//1
theGraph.addVertex('C');//2
theGraph.addVertex('D');//3
theGraph.addVertex('E');//4
theGraph.addEdge(0, 1);// AB
theGraph.addEdge(1, 2);// BC
theGraph.addEdge(0, 3);// AD
theGraph.addEdge(3, 4);// DE
/*
A--B--C
|
D--E
*/
System.out.print("Visits:");
theGraph.bfs();// breadth-first search
System.out.println();//Visits:ABDCE
}
}
mst
MSTApp
package mst;
/**
* @author CSDN@日星月云
* @date 2022/10/26 18:37
* mst
* 最小生成树
*/
class Vertex {
public char label;// label (e.g. 'A')
public boolean wasVisited;
public Vertex(char lab){// constructor
label = lab;
wasVisited = false;
}
}
class Graph {
private final int MAX_VERTS = 20;
private Vertex vertexList[]; // array of vertices
private int adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
private StackX theStack;
//------------------------------------------------------------
public Graph() { // constructor
vertexList = new Vertex[MAX_VERTS];// adjacency matrix
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int j = 0; j < MAX_VERTS; j++)// set adjacency
for (int k = 0; k < MAX_VERTS; k++)//matrix to 0
adjMat[j][k] = 0;
theStack = new StackX();
}// end constructor
//------------------------------------------------------------
public void addVertex(char lab) {// argument is label
vertexList[nVerts++] = new Vertex(lab);
}
//------------------------------------------------------------
public void addEdge(int start, int end) {
adjMat[start][end] = 1;
adjMat[end][start] = 1;
}
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
//------------------------------------------------------------
// returns an unvisited vertex adjacent to v
public int getAdjUnvisitedVertex(int v) {
for (int j = 0; j < nVerts; j++)
if (adjMat[v][j] == 1 && vertexList[j].wasVisited == false)
return j;// return first such vertex
return -1;// no such vertices
} // end getAdjUnvisitedVertex()
//最小生成树
public void mst() {// minimum spanning tree (depth first)
// start at 0
vertexList[0].wasVisited = true;// mark it
theStack.push(0);// push it
while (!theStack.isEmpty()) {// until stack empty
// get stack top
int currentVertex = theStack.peek();
//get next unvisited neighbor
int v = getAdjUnvisitedVertex(currentVertex);
if (v == -1) {
// if no more neighbors
theStack.pop();// pop it away
} else { // got a neighbor
vertexList[v].wasVisited = true; // mark it
theStack.push(v);// push it
// display edge
displayVertex(currentVertex);// from currentV
displayVertex(v);// to v
System.out.print(" ");
}
}// end while(stack not empty)
// stack is empty, so we're done
for (int j = 0; j < nVerts; j++) {// reset flags
vertexList[j].wasVisited = false;
} // end tree
}
}// end class Graph
public class MSTApp{
//测试 mst
public static void main(String[] args) {
Graph theGraph = new Graph();
theGraph.addVertex('A');//0 (start for dfs)
theGraph.addVertex('B');//1
theGraph.addVertex('C');//2
theGraph.addVertex('D');//3
theGraph.addVertex('E');//4
theGraph.addEdge(0, 1);// AB
theGraph.addEdge(0, 2);// AC
theGraph.addEdge(0, 3);// AD
theGraph.addEdge(0, 4);// AE
theGraph.addEdge(1, 2);// BC
theGraph.addEdge(1, 3);// BD
theGraph.addEdge(1, 4);// BD
theGraph.addEdge(2, 3);// CD
theGraph.addEdge(2, 4);// CE
theGraph.addEdge(3, 4);// DE
/*
A--B--C
|
D--E
*/
System.out.print("Minimum spanning tree:");
theGraph.mst(); // minimum spanning tree
System.out.println(); // AB BC CD DE
}
}
topo
TopoApp
package topo;
/**
* @author CSDN@日星月云
* @date 2022/10/26 18:37
* 有向图
* topo
* 拓扑排序
* 步骤1找到一个没有后继的顶点。
* 步骤2从图中删除这个顶点,在列表的前面插入顶点的标记。
* 重复步骤1和步骤2,直到所有顶点都从图中删除。
* 这时,列表显示的顶点顺序就是拓扑排序的结果。
*/
class Vertex {
public char label;// label (e.g. 'A')
public boolean wasVisited;
public Vertex(char lab) {// constructor
label = lab;
wasVisited = false;
}
}
class Graph {
private final int MAX_VERTS = 20;
private Vertex vertexList[]; // array of vertices
private int adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
private char[] sortedArray;
//------------------------------------------------------------
public Graph() { // constructor
vertexList = new Vertex[MAX_VERTS];// adjacency matrix
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int j = 0; j < MAX_VERTS; j++)// set adjacency
for (int k = 0; k < MAX_VERTS; k++)//matrix to 0
adjMat[j][k] = 0;
sortedArray = new char[MAX_VERTS];// sorted vert labels
}// end constructor
//------------------------------------------------------------
public void addVertex(char lab) {// argument is label
vertexList[nVerts++] = new Vertex(lab);
}
//------------------------------------------------------------
public void addEdge(int start, int end) {
adjMat[start][end] = 1;
}
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
//------------------------------------------------------------
public void topo() {// topological sort
int orig_nVerts = nVerts; // remember how many verts
while (nVerts > 0) { // while vertices remain,
// get a vertex with no successors, or -1
int currentVertex = noSuccessors();
if (currentVertex == -1) {// must be a cycle
System.out.println("ERROR: Graph has cycles");
return;
}
// insert vertex label in sorted array (start at end)
sortedArray[nVerts - 1] = vertexList[currentVertex].label;
deleteVertex(currentVertex); // delete vertex}
}// end while
// vertices all gone;display sortedArray
System.out.print("Topologically sorted order: ");
for (int j = 0; j < orig_nVerts; j++) {
System.out.print(sortedArray[j]);
}
System.out.println("");
}// end topo
/**
*主要工作在while循环中进行。这个循环直到顶点数目为0时才退出。下面是步骤:
* 1.调用noSuccessors()找到任意一个没有后继的顶点。
* 2.如果找到一个这样的顶点,把顶点放入数组sortedArray[],并且从图中删除顶点。
* 3.如果没有这样的顶点,则图必然存在环。
*
* 最后一个被删除的顶点出现在列表的开头,所以,随着nVerts (图中顶点个数)逐渐变小,顶
* 点从sortedArray数组的最后开始,依次向前排列。
*
* 如果有顶点还在图中,但它们都有后继,那么图必然存在环,算法会显示一条信息并退出。如
* 果没有环,则while循环退出,显示sortedArray数组中的数据,这时顶点是按拓扑有序排列。
*
*/
/**
* noSuccessorsO方法使用邻接矩阵找到没有后继的顶点。在外层for循环中,沿着每一行考察每
* 个顶点。在每行中,用内层for循环扫描列,査找值为1的顶点。如果找到一个,就说明顶点有后
* 继,因为从这个顶点到其他点有边存在。当找到一个1时,跳出内层循环,考察下一个顶点。
* <p>
* 只有整个一行都没有1存在,才说明有一个顶点没有后继;这时,就返回它的行号。如果没有
* 这样的顶点,就返回-1。下面是noSuccessors()方法:
*/
public int noSuccessors() {// returns vert with no successors
// (or -1 if no such verts)
boolean isEdge; // edge from row to column in adjMat
for (int row = 0; row < nVerts; row++) { // for each vertex,
isEdge = false;
for (int col = 0; col < nVerts; col++) { // check edges
if (adjMat[row][col] > 0) { // if edge to
// another,
isEdge = true; // this vertex
break;
}//has a successor
}// try another
if (!isEdge)// if no edges,
return row; // has no successor
}
return -1;// no such vertex
}// end noSuccessors()
/**
* 除了一些细节外,删除一个顶点很简单。顶点从vertexList[]数组删除,后面的顶点向前移动填
* 补空位。同样的,顶点的行列从邻接矩阵中删除,下面的行和右面的列移动来填补空位。这些任务
* 由delete Vertex。、moveRowUp()和moveColLeft ()方法来完成。这些方法将在topo.java程序的完整
* 代码(清单13.4)中看到。对于这个算法,用邻接表表示图效率更高,但要使用更多空间。
*/
public void deleteVertex(int delVert) {
if (delVert != nVerts - 1) {// if not last vertex,
// delete from vertexList
for (int j = delVert; j < nVerts - 1; j++)
vertexList[j] = vertexList[j + 1];
// delete row from adjMat
for (int row = delVert; row < nVerts - 1; row++)
moveRowUp(row, nVerts);
// delete col from adjMat
for (int col = delVert; col < nVerts - 1; col++)
moveColLeft(col, nVerts - 1);
}
nVerts--;// one less vertex
}// end deleteVertex
private void moveRowUp(int row, int length) {
for (int col = 8; col < length; col++) {
adjMat[row][col] = adjMat[row + 1][col];
}
}
private void moveColLeft(int col, int length) {
for (int row = 0; row < length; row++)
adjMat[row][col] = adjMat[row][col + 1];
}
}// end class Graph
public class TopoApp {
/**
* main。例程调用一些方法创建如图13.10所示的图,这些方法与前面看到的类似。应该注意到,
* addEdge()方法只在邻接矩阵中插入一个数,因为这是有向图。下面是main()方法的代码:
*/
public static void main(String[] args) {
Graph theGraph = new Graph();
theGraph.addVertex('A');//0
theGraph.addVertex('B');//1
theGraph.addVertex('C');//2
theGraph.addVertex('D');//3
theGraph.addVertex('E');//4
theGraph.addVertex('F');//5
theGraph.addVertex('G');//6
theGraph.addVertex('H');//7
theGraph.addEdge(0, 3);// AD
theGraph.addEdge(0, 4);// AE
theGraph.addEdge(1, 4);// BE
theGraph.addEdge(2, 5);// CF
theGraph.addEdge(3, 6);// DG
theGraph.addEdge(4, 6);// EG
theGraph.addEdge(5, 7);// FH
theGraph.addEdge(6, 7);// GH
theGraph.topo();// do the sort
/*
Topologically sorted order: GBAEDCFH
*/
}// end main()
}// end class TopoApp
pstw
MSTWApp
package pstw;
/**
* @author CSDN@日星月云
* @date 2022/10/27 15:09
*
* 最小生成树
* 无向带权图
* 从一个顶点开始,把它放入树的集合中。然后重复做下面的事情:
* 1.找到从最新的顶点到其他顶点的所有边,这些顶点不能在树的集合中。把这些边放入优先级队列。
* 2.找岀权值最小的边,把它和它所到达的顶点放入树的集合中。
* 重复这些步骤,直到所有顶点都在树的集合中。这时,工作完成。
*/
/**
* PriorityQ类用数组存储对象。正如前面提到的,在处理大量数据的程序中,用堆存储对象比数
* 组更合适。PriorityQ类已经增加了不同的方法,如前所示,它用find()方法找到到达指定顶点的边;
* 用peekN()方法得到任意一个数据项;用removeN()方法删除任意一个数据项。程序的其余部分前面
* 已经看到。清单14.1显示了完整的mstw.java程序。
*/
//mstw.java
// demonstrates minimum spanning tree with weighted graphs
// to run this program: C>java MSTWApp
class Edge {
public int srcVert; //index of a vertex starting edge
public int destVert; //index of a vertex ending edge
public int distance; //distance from src to dest
//-------------------------------------------
public Edge(int sv, int dv, int d) // constructor
{
srcVert = sv;
destVert = dv;
distance = d;
}
//
}// end class Edge
class PriorityQ {
// array in sorted order, from max at 0 to min at size-1
private final int SIZE = 20;
private Edge[] queArray;
private int size;
//-------------------------------------------
public PriorityQ() { // constructor
queArray = new Edge[SIZE];
size = 0;
}
//
public void insert(Edge item) {//If insert item in sorted order
int j;
for (j = 0; j < size; j++) // find place to insert
if (item.distance >= queArray[j].distance)
break;
for (int k = size - 1; k >= j; k--) // move items up
queArray[k + 1] = queArray[k];
queArray[j] = item; // insert item
size++;
}
//
public Edge removeMin() {// remove minimum item
return queArray[--size];
}
public void removeN(int n) { // remove item at n
for (int j = n; j < size - 1; j++) // move items down
queArray[j] = queArray[j + 1];
size--;
}
//
public Edge peekMin() { // peek at minimum item
return queArray[size - 1];
}
//
public int size() {// return number of items
return size;
}
//
public boolean isEmpty() { // true if queue is empty
return (size == 0);
}
//
public Edge peekN(int n) { // peek at item n
return queArray[n];
}
public int find(int findDex) { // find item with specified
// destVert value
for (int j = 0; j < size; j++)
if (queArray[j].destVert == findDex)
return j;
return -1;
}
}//end class PriorityQ
class Vertex {
〃// class Vertex
public char label; // label (e.g. 'A1)
public boolean isInTree;
//
public Vertex(char lab) { // constructor
label = lab;
isInTree = false;
}
//
} // end class Vertex
class Graph {
private final int MAX_VERTS = 20;
private final int INFINITY = 1000000;
private Vertex vertexList[];// list of vertices
private int adjMat[][];// adjacency matrix
private int nVerts; // current number of vertices
private int currentVert;
private PriorityQ thePQ;
private int nTree; // number of verts in tree
public Graph() // constructor
{
vertexList = new Vertex[MAX_VERTS];
// adjacency matrix
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for (int j = 0; j < MAX_VERTS; j++) // set adjacency
for (int k = 0; k < MAX_VERTS; k++) // matrix to 0
adjMat[j][k] = INFINITY;
thePQ = new PriorityQ();
}//end constructor
//
public void addVertex(char lab) {
vertexList[nVerts++] = new Vertex(lab);
}
public void addEdge(int start, int end, int weight) {
adjMat[start][end] = weight;
adjMat[end][start] = weight;
}
//
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
/**
* 根据前面的算法要点,编制有向图最小生成树的方法mstw()。正如其他图的程序一样,假定在
* vertexList[]数组中有一个顶点列表,并且从下标为0的顶点开始。currentVert代表最近加到树中的
* 顶点。下面是mstw()方法的代码:
*/
public void mstw() // minimum spanning tree
{
currentVert = 0; // start at 0
while (nTree < nVerts - 1) { // while not all verts in tree
// put currentVert in tree
vertexList[currentVert].isInTree = true;
nTree++;
// insert edges adjacent to currentVert into PQ
for (int j = 0; j < nVerts; j++) {// for each vertex,
if (j == currentVert)// skip if it 's us
continue;
if (vertexList[j].isInTree) // skip if in the tree
continue;
int distance = adjMat[currentVert][j];
if (distance == INFINITY)
continue;
putInPQ(j, distance);//put it in PQ (maybe)
}
if (thePQ.size() == 0) {//no vertices in PQ?
System.out.println("GRAPH NOT CONNECTED");
return;
}
// remove edge with minimum distance, from PQ
Edge theEdge = thePQ.removeMin();
int sourceVert = theEdge.srcVert;
currentVert = theEdge.destVert;
// display edge from source to current
System.out.print(vertexList[sourceVert].label);
System.out.print(vertexList[currentVert].label);
System.out.print(" ");
}// end while( not all verts in tree)
// mst is complete
for (int j = 0; j < nVerts; j++) // unmark vertices
vertexList[j].isInTree = false;
} // end mstw
/**
* 算法在while循环中执行,循环结束条件是所有顶点都己在树中。循环中完成下面的操作:
* 1.当前顶点放在树中。
* 2.连接这个顶点的边放到优先级队列中(如果合适)。
* 3.从优先级队列中删除权值最小的边。这条边的目的顶点变成当前顶点。
* 再看看这些步骤的细节。在步骤1中,通过标记currentVert所指顶点的isInTree字段来表示该
* 顶点放入树中。
* 在步骤2中,连接这个顶点的边插入优先级队列。通过在邻接矩阵中扫描行号是currentVert的
* 行寻找需要的边。只要下面任意一个条件为真,这条边就不能放入队列中:
* •源点和终点相同。
* •终点在树中。
* •源点和终点之间没有边(邻接矩阵中对应的值等于无限大)。
* 如果没有一个条件为真,调用putlnPQO方法把这条边放入队列中。实际上,正如下面要看到
* 的,这个例程并不总把边放到队列中。
* 在步骤3中,将最小权值的边从优先级队列中删除。把这条边和该边的终点加入树,并显示源
* 点(currentVert)和终点。
*在mstw()方法最后,所有顶点的isInTree变量被重置,即从树中删除。在该程序中这样做,是
* 因为根据这些数据只能创建一棵树。然而,在完成一项工作后,最好把数据恢复到原始的形态。
*/
/**
* 正如前面所强调的,在优先级队列中应该只含有一条到达某个特定目标顶点的边。putlnPQ()
* 方法保证了这一点。它调用PriorityQ类的find()方法,这个方法经过修正,可以寻找到达指定点的
* 边。如果不存在到达指定点的边,find。方法返回一1,这时putlnPQ()方法只要把新边插入优先级队
* 列中即可。然而,如果有到达指定点的老边存在,putlnPQ()方法就要检査老边是否比新边有更小的
* 权值。如果老边的权值小,就不需要作什么变化。如果新边有更小的权值,就要把老边从队列中删
* 除,把新边放进去。下面是putlnPQO方法的代码:
*/
public void putInPQ(int newVert, int newDist) {
//is there another edge with the same destination vertex?
int queueIndex = thePQ.find(newVert);
if (queueIndex != -1) { // got edge's index
Edge tempEdge = thePQ.peekN(queueIndex);// get edge
int oldDist = tempEdge.distance;
if (oldDist > newDist) { // if new edge shorter,
thePQ.removeN(queueIndex); // remove old edge
Edge theEdge = new Edge(currentVert, newVert, newDist);
thePQ.insert(theEdge); // insert new edge
}
// else no action; just leave the old vertex there
} // end if
else { //no edge with same destination vertex
//so insert new one
Edge theEdge = new Edge(currentVert, newVert, newDist);
thePQ.insert(theEdge);
}
} // end putInPQ()
} // end class Graph
class MSTWApp {
public static void main(String[] args) {
Graph theGraph = new Graph();
theGraph.addVertex('A');//0 (start for mst)
theGraph.addVertex('B');//1
theGraph.addVertex('C');//2
theGraph.addVertex('D');//3
theGraph.addVertex('E');//4
theGraph.addVertex('F');//5
theGraph.addEdge(0, 1, 6);//AB 6
theGraph.addEdge(0, 3, 4);//AD 4
theGraph.addEdge(1, 2, 10);//BC 10
theGraph.addEdge(1, 3, 7);//BD 7
theGraph.addEdge(1, 4, 7);//BE 7
theGraph.addEdge(2, 3, 8);//CD 8
theGraph.addEdge(2, 4, 5);//CE 5
theGraph.addEdge(2, 5, 6);//CF 6
theGraph.addEdge(3, 4, 12);//DE 12
theGraph.addEdge(4, 5, 7);//EF 7
System.out.print("Minimum spanning tree: ");
theGraph.mstw(); // minimum spanning tree
System.out.println();//Minimum spanning tree: AD AB BE EC CF
}// end main()
}//end class MSTWApp
///