无向图--邻接矩阵、连接矩阵、深度遍历、广度遍历、生成树

时间:2021-01-29 12:34:45


无向图--邻接矩阵、连接矩阵、深度遍历、广度遍历、生成树 1、开始生成的无向图
无向图--邻接矩阵、连接矩阵、深度遍历、广度遍历、生成树 2、由图深度优先遍历生成的树

 

 

package graph;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;


public class GraphTest {

public static void main(String[] args) {
AdjacencyMatrixGraph a = new AdjacencyMatrixGraph(6);
a.addVertex("A");
a.addVertex("B");
a.addVertex("C");
a.addVertex("D");
a.addVertex("E");
a.addVertex("F");

a.addEdge(0, 1);
a.addEdge(1, 2);
a.addEdge(0, 3);
a.addEdge(2, 4);
a.addEdge(0, 2);
a.addEdge(0, 4);
a.addEdge(3, 5);

a.printMatrix();

a.traverseDepth();
System.out.println();
a.traverseBroad();

System.out.println();

a.growMinTree();
System.out.println();
a.traverseBroad();


//ConnectionMatrixGraph con = new ConnectionMatrixGraph();
//con.addVertex("A");
//con.addVertex("B");
//con.addVertex("C");
//con.addVertex("D");
//
//con.addEdge(0, 1);
//con.addEdge(0, 3);
//con.addEdge(1, 2);
//con.addEdge(0, 2);
//con.addEdge(2, 3);
//
//con.printConnectionMatrix();

//con.traverseBroad();
}
}

/**
* 采用邻接矩阵的无向图
* @author LiangYH
*
*/
class AdjacencyMatrixGraph{
//最大顶点数的容量
private int maxSize;
//存放顶点
private List<Vertex> vertexList;
//邻接矩阵,存放点和点的关系
private int[][] adjacencyMatrix;

public AdjacencyMatrixGraph(int maxSize){
this.maxSize = maxSize;
this.vertexList = new ArrayList<Vertex>();
adjacencyMatrix = new int[maxSize][maxSize];
}

public boolean isFull(){
return vertexList.size() >= maxSize;
}

//增加顶点
public void addVertex(String label){
if(isFull())
throw new ArrayIndexOutOfBoundsException("数组已经满了");
vertexList.add(new Vertex(label));
}

//增加边
public void addEdge(int vertexIndex1, int vertexIndex2){
int size = getSize();
if(vertexIndex1 >= size || vertexIndex2 >= size)
throw new ArrayIndexOutOfBoundsException();

this.adjacencyMatrix[vertexIndex1][vertexIndex2] = 1;
this.adjacencyMatrix[vertexIndex2][vertexIndex1] = 1;
}

/**
* 深度优先遍历图
*/
public void traverseDepth(){
Stack<Vertex> s = new Stack<>();

System.out.print(vertexList.get(0).getLabel());
vertexList.get(0).setVisited(true);

int targetIndex = 0;
while(true){
int size = getSize();
for(int i = 0; i < size; i++){
if((!vertexList.get(i).isVisited()) && adjacencyMatrix[targetIndex][i] == 1){

Vertex temp = vertexList.get(i);
temp.setVisited(true);

System.out.print(vertexList.get(i).getLabel());

s.push(vertexList.get(targetIndex));
targetIndex = i;
i = 0;
}
}
if(!s.isEmpty()){
Vertex tempV = s.pop();
targetIndex = findVertex(tempV);
}else{
break;
}
}
//恢复
int len = vertexList.size();
for(int i = 0; i < len; i++){
vertexList.get(i).setVisited(false);
}
}

/**
* 广度优先遍历图
*/
public void traverseBroad(){
Queue<Vertex> q = new LinkedList<>();
//第一个访问的是第一个顶点
System.out.print(vertexList.get(0).getLabel());
vertexList.get(0).setVisited(true);
//当前所在的节点
int targetIndex = 0;
int size = getSize();
while(true){
for(int i = 0; i < size; i++){
//是否已经被访问过以及是否有边的联系
if((!vertexList.get(i).isVisited()) && adjacencyMatrix[targetIndex][i] == 1){
Vertex t = vertexList.get(i);
q.add(t);
t.setVisited(true);
System.out.print(vertexList.get(i).getLabel());
}
}
if(!q.isEmpty()){
//从队列中弹出顶点
Vertex tempV = q.poll();
//改变当前所在的节点下标
targetIndex = findVertex(tempV);
}else{
break;
}
}
//恢复
int len = vertexList.size();
for(int i = 0; i < len; i++){
vertexList.get(i).setVisited(false);
}
}

private int findVertex(Vertex vertex){
for(int i = 0; i < vertexList.size(); i++){
if(vertex == vertexList.get(i))
return i;
}
return -1;
}

public int getSize(){
return this.vertexList.size();
}

/**
* 最小生成树
* 思路:和上面的深度优先遍历图的方法基本相同,只是下面的method是在遍历的同时记录下了边的关系。
*/
public void growMinTree(){
int len2 = vertexList.size();
int[][] tempDyadic = new int[len2][len2];


Stack<Vertex> s = new Stack<>();

System.out.print(vertexList.get(0).getLabel());
vertexList.get(0).setVisited(true);

int targetIndex = 0;
while(true){
int size = getSize();
for(int i = 0; i < size; i++){
if((!vertexList.get(i).isVisited()) && adjacencyMatrix[targetIndex][i] == 1){
//最小生成树的邻接矩阵的关键:标记访问过并且有链接的连线,放在新的二维数组中
tempDyadic[targetIndex][i] = 1;

Vertex temp = vertexList.get(i);
temp.setVisited(true);

System.out.print(vertexList.get(i).getLabel());

s.push(vertexList.get(targetIndex));
targetIndex = i;
i = 0;
}
}
if(!s.isEmpty()){
Vertex tempV = s.pop();
targetIndex = findVertex(tempV);
}else{
break;
}
}
//恢复为都未访问过
int len = vertexList.size();
for(int i = 0; i < len; i++){
vertexList.get(i).setVisited(false);
}
//打印邻接矩阵
System.out.println();
System.out.println("最小生成树的邻接矩阵:");
for(int i = 0; i < len; i++){
for(int k = 0; k < len; k++){
System.out.print(tempDyadic[i][k]+" ");
}
System.out.println();
}
//改变矩阵的引用
adjacencyMatrix = tempDyadic;
}

public void printMatrix(){
System.out.println("图的邻接矩阵: ");
int len = vertexList.size();
for(int i = 0; i < len; i++){
for(int k = 0; k < len; k++){
System.out.print(adjacencyMatrix[i][k]+" ");
}
System.out.println();
}
}
}


/**
* 采用连接矩阵的无向图
* @author admin
*
*/
class ConnectionMatrixGraph{
//private LinkedList<Vertex> vertexList;
private LinkedList<LinkedList<Vertex>> connectionMatrix;

public ConnectionMatrixGraph(){
//vertexList = new ArrayList<>();
connectionMatrix = new LinkedList<>();
}

public void addVertex(String label){
LinkedList<Vertex> v = new LinkedList<Vertex>();
v.add(new Vertex(label));
connectionMatrix.add(v);
}

public void addEdge(int a, int b){
LinkedList<Vertex> vlist1 = this.connectionMatrix.get(a);
LinkedList<Vertex> vlist2 = this.connectionMatrix.get(b);

vlist1.add(vlist2.get(0));
vlist2.add(vlist1.get(0));
}

/**
* 打印链接矩阵
*/
public void printConnectionMatrix(){
java.util.Iterator<LinkedList<Vertex>> iter = connectionMatrix.iterator();
while(iter.hasNext()){
LinkedList<Vertex> tempLink = iter.next();
java.util.Iterator<Vertex> iter2 = tempLink.iterator();
while(iter2.hasNext()){
Vertex v = iter2.next();
System.out.print(v.getLabel()+"-->");
}
System.out.println();
}
}

/**
* 图的广度优先遍历,不需栈
*/
public void traverseBroad(){
Iterator<LinkedList<Vertex>> iter = null;
iter = connectionMatrix.iterator();
while(iter.hasNext()){
LinkedList<Vertex> tempLink = iter.next();
Iterator<Vertex> iter2 = null;
iter2 = tempLink.iterator();

Vertex tempV2 = null;
if(iter2.hasNext()){
tempV2 = iter2.next();
//如果没有访问过
if(!tempV2.isVisited()){
tempV2.setVisited(true);
System.out.print(tempV2.getLabel());
}
}else{
continue;
}
while(iter2.hasNext()){
Vertex tempV = iter2.next();
if(!tempV.isVisited()){
tempV.setVisited(true);
System.out.print(tempV.getLabel());
}
}
}
}

}

/**
* 顶点
* @author admin
*
*/
class Vertex{
private String label;
private boolean isVisited;

public Vertex(String label){
this.label = label;
this.isVisited = false;
}

public String getLabel() {
return label;
}

public void setLabel(String label) {
this.label = label;
}

public boolean isVisited() {
return isVisited;
}

public void setVisited(boolean isVisited) {
this.isVisited = isVisited;
}

}


结果:
无向图--邻接矩阵、连接矩阵、深度遍历、广度遍历、生成树