您的位置:首页 > 其它

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

2015-09-15 13:46 573 查看

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;
	}
	
}
结果:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: