/**
* 对外公开的深度优先遍历
*/
public void depthFirstSearch() {
isVisited = new boolean[vertexSize];
for (int i = 0; i < vertexSize; i++) {
if (!isVisited[i]) {
System.out.println("被访问到了:" + i + "顶点");
depthFirstSearch(i);
}
}
isVisited = new boolean[vertexSize];
}
/**
* 图的深度优先遍历算法
* @param i
*/
private void depthFirstSearch(int i) {
isVisited[i] = true;
int w = getFirstNeighbor(i);
while (w != -1) {
if (!isVisited[w]) {
//需要遍历该顶点
System.out.println("被访问到了:" + w + "顶点");
depthFirstSearch(w);
}
w = getNextNeighbor(i, w);
}
}
/**
* 获取某个顶点的第一个邻接点
*
* @param index
* @return
*/
public int getFirstNeighbor(int index) {
for (int j = 0; j < vertexSize; j++) {
if (matrix[index][j] > 0 && matrix[index][j] < MAX_WEIGHT) {
return j;
}
}
return -1;//无邻接点
}
/**
* 根据前一个邻接点的下标来获取下一个邻接点
*
* @param v1 要找的顶点
* @param v2 表示该顶点相对于那个邻接点去获取下一个邻接点
* @return
*/
public int getNextNeighbor(int v1, int v2) {
for (int j = v2 + 1; j < vertexSize; j++) {
if (matrix[v1][j] > 0 && matrix[v1][j] < MAX_WEIGHT) {
return j;
}
}
return -1;
}
public void dfs() {
// 初始化所有的节点的访问标志
for (int v = 0; v < visited.length; v++) {
visited[v] = false;
}
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < vexnum; i++) {
if (visited[i] == false) {
visited[i] = true;
System.out.print(vertices[i] + " ");
stack.push(i);
}
while (!stack.isEmpty()) {
// 当前出栈的节点
int k = stack.pop();
for (int j = 0; j < vexnum; j++) {
// 如果是相邻的节点且没有访问过.
if (arcs[k][j] == 1 && visited[j] == false) {
visited[j] = true;
System.out.print(vertices[j] + " ");
stack.push(j);
// 这条路结束,返回上一个节点.
break;
}
}
}
} // 输出二维矩阵
System.out.println();
pritf(arcs);
}
/**
* 输出邻接矩阵
*/
public void pritf(int[][] arcs) {
for (int i = 0; i < arcs.length; i++) {
for (int j = 0; j < arcs[0].length; j++) {
System.out.print(arcs[i][j] + "\t");
}
System.out.println();
}
}
public void broadFirstSearch() {
isVisited = new boolean[vertexSize];
for (int i = 0; i < vertexSize; i++) {
if (!isVisited[i]) {
broadFirstSearch(i);
}
}
}
/**
* 实现广度优先遍历(队列)
*
* @param i
*/
private void broadFirstSearch(int i) {
int u, w;
LinkedList<Integer> queue = new LinkedList<>();
System.out.println("被访问到了:" + i + "顶点");
isVisited[i] = true;
queue.add(i);//第一次把v0加到队列
while (!queue.isEmpty()) {
u = queue.removeFirst();
w=getFirstNeighbor(u);
while (w!=-1){
if (!isVisited[w]){
System.out.println("被访问到了:" + w + "顶点");
isVisited[w]=true;
queue.add(w);
}
w=getNextNeighbor(u,w);
}
}
}
/**
* prim 普里姆算法
*/
public void prim(){
int[] lowcost=new int[vertexSize];//最小代价顶点权值的数组,为0表示已经获取最小权值
int[] adjvex=new int[vertexSize];//放顶点权值
int min,minId,sum=0;
for (int i=1;i<vertexSize;i++){
lowcost[i]=matrix[0][i];
}
for (int i=1;i<vertexSize;i++){
min=MAX_WEIGHT;
minId=0;
for (int j=1;j<vertexSize;j++){
if (lowcost[j]<min&&lowcost[j]>0){
min=lowcost[j];
minId=j;
}
}
System.out.println("顶点:"+adjvex[minId]+"权值:"+min);
sum+=min;
lowcost[minId]=0;
for (int j=0;j<vertexSize;j++){
if (lowcost[j]!=0&&matrix[minId][j]<lowcost[j]){
lowcost[j]=matrix[minId][j];
adjvex[j]=minId;
}
}
}
System.out.println("权值总和:"+sum);
}
先构造一个只含 n 个顶点、而边集为空的子图,把子图中各个顶点看成各棵树上的根结点,之后,从网的边集 E
中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,即把两棵树合成一棵树,反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直到森林中只有一棵树,也即子图中含有 n-1 条边为止。
/**
* 克鲁斯卡尔算法最小生成树
*/
public void miniSpanTreeKruskal(){
int m,n,sum=0;
int[] parent=new int[edgeSize];//神奇的数组,下标为起点,值为终点
for (int i = 0; i < edgeSize; i++) {
parent[i]=0;
}
for (int i = 0; i < edgeSize; i++) {
n=find(parent,edges[i].begin);
m=find(parent,edges[i].end);
if (n!=m){
parent[n]=m;
System.out.println("起始顶点:"+edges[i].begin+"结束顶点:"+edges[i].end+"权值:"+edges[i].weight);
sum+=edges[i].weight;
}else {
System.out.println("第"+i+"边回环了!");
}
}
System.out.println("权值总和:"+sum);
}
/**
* 将神奇数组进行查询获取非回环的值
* @param parent
* @param f
* @return
*/
private int find(int[] parent, int f) {
while (parent[f]>0){
System.out.println("找到起点:"+f);
f=parent[f];
System.out.println("找到终点:"+f);
}
return f;
}
public void createEdgeArray(){
Edge edge0 = new Edge(4,7,7);
Edge edge1 = new Edge(2,8,8);
Edge edge2 = new Edge(0,1,10);
Edge edge3 = new Edge(0,5,11);
Edge edge4 = new Edge(1,8,12);
Edge edge5 = new Edge(3,7,16);
Edge edge6 = new Edge(1,6,16);
Edge edge7 = new Edge(5,6,17);
Edge edge8 = new Edge(1,2,18);
Edge edge9 = new Edge(6,7,19);
Edge edge10 = new Edge(3,4,20);
Edge edge11 = new Edge(3,8,21);
Edge edge12 = new Edge(2,3,22);
Edge edge13 = new Edge(3,6,24);
Edge edge14 = new Edge(4,5,26);
edges[0] = edge0;
edges[1] = edge1;
edges[2] = edge2;
edges[3] = edge3;
edges[4] = edge4;
edges[5] = edge5;
edges[6] = edge6;
edges[7] = edge7;
edges[8] = edge8;
edges[9] = edge9;
edges[10] = edge10;
edges[11] = edge11;
edges[12] = edge12;
edges[13] = edge13;
edges[14] = edge14;
}
class Edge{
private int begin;
private int end;
private int weight;
public Edge(int begin, int end, int weight) {
this.begin = begin;
this.end = end;
this.weight = weight;
}
}