首页 > 代码库 > 图的所有简单算法实现

图的所有简单算法实现

包括邻接链表、有向无向图、带权图、增删顶点和边、查找、连通、DFS和BFS等。这只是一个最初版本,有些复杂的算法还没有实现。

package structure;
//图的邻接链表的节点
public class GraphListNode {
	
	private int vertex;//图的顶点
	private int weight;//边的权重
	private boolean visited;//是否访问过
	
	
	//带权重图的节点
	public GraphListNode(int vertex,int weight){
		this.vertex = vertex;
		this.weight = weight;
		this.visited = false;//默认为未访问
	}
	
	public boolean isVisited() {
		return visited;
	}

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

	public int getVertex() {
		return vertex;
	}
	public void setVertex(int vertex) {
		this.vertex = vertex;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}	
	
}

下面就是图的实现了,还有测试代码

package structure;


import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;


//邻接链表表示的图
public class AdjacencyListGraph {
	
	private LinkedList<LinkedList<GraphListNode>> vertexList;//点链表
	
	public LinkedList<LinkedList<GraphListNode>> getVertexList() {
		return vertexList;
	}
	
	//图中是否包含某个顶点
	public boolean contains(int vertex){
		Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()) {
			//如果当前顶点的边链表已经存在,直接返回
			if (itr.next().get(0).getVertex() == vertex) {
				return true;
			}
		}
		return false;
	}

	public AdjacencyListGraph(){
		this.vertexList = new LinkedList<LinkedList<GraphListNode>>();
	}
	
	
	//增加一个顶点
	public void addVertexSingle(int vertexNo){
		
		if (contains(vertexNo)) {
			return;
		}
			
		//定义一个以vertexNo为头的边链表
		LinkedList<GraphListNode> ll = new LinkedList<GraphListNode>();
		ll.add(new GraphListNode(vertexNo,0));
		//将边链表加入到点链表中
		vertexList.add(ll);
	}
	
	//单向删除一个顶点
	public void deleteVertexSingle(int vertexNo){
		Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()) {
			//找到相应点对应的边链表,删除
			LinkedList<GraphListNode> ll = itr.next();
			if (ll.get(0).getVertex() == vertexNo) {
				itr.remove();
				break;
			}
		}
	}
	
	//双向删除一个顶点
	public void deleteVertexDouble(int vertexNo){
		Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()) {
			//找到相应点对应的边链表,删除
			LinkedList<GraphListNode> ll = itr.next();
			if (ll.get(0).getVertex() == vertexNo) {
				itr.remove();
				break;
			}
		}
		itr = vertexList.listIterator();
		//删除所有的相关记录
		while(itr.hasNext()){
			LinkedList<GraphListNode> ll = itr.next();
			Iterator<GraphListNode> li = ll.listIterator();
			while (li.hasNext()) {
				if (li.next().getVertex() == vertexNo) {
					li.remove();
				}				
			}		
		}
	}
	
	
	//双向增加
	public void addEdgeDouble(int vertexNoU,int vertexNoV){
		addEdgeDouble(vertexNoU, vertexNoV, 0);
	}
	
	public void addEdgeDouble(int vertexNoU,int vertexNoV,int weight){
		updateEdge(vertexNoU, vertexNoV, weight);
		updateEdge(vertexNoV, vertexNoU, weight);
	}
	
	//增加一个不带权重的从u到v的边
	public void addEdgeSingle(int vertexNoU,int vertexNoV){
		updateEdge(vertexNoU, vertexNoV,0);
	}
	
	public void addEdgeSingle(int vertexNoU,int vertexNoV,int weight){
		updateEdge(vertexNoU, vertexNoV,weight);
	}
	
	//增加或修改一条从u到v,权重为weight的边
	public void updateEdge(int vertexNoU,int vertexNoV,int weight){
		
		Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()) {
			//检测以vertexNoU为顶点的边链表是否存在
			LinkedList<GraphListNode> ll  = itr.next();
			if (ll.get(0).getVertex() == vertexNoU) {
				//检测在该边链表中是否已经存在从u到v的边
				Iterator<GraphListNode> it = ll.listIterator();
				while (it.hasNext()) {
					if (it.next().getVertex() == vertexNoV) {
						//如果已经存在该边,直接更新权重
						it.next().setWeight(weight);
						return;
					}				
				}
				//如果不存在该边,则增加该边
				ll.add(new GraphListNode(vertexNoV, weight));
				return;
			}
		}
		//如果不存在顶点vertexNoU,增加顶点U,然后增加边uv
		addVertexSingle(vertexNoU);
		updateEdge(vertexNoU, vertexNoV, weight);
	}
	
	//双向设置标记
	public void setMarkDouble(int vertexNo,boolean flag){
		ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()){
			LinkedList<GraphListNode> ll = itr.next();
			for (GraphListNode gln: ll) {
				if (gln.getVertex() == vertexNo) {
					gln.setVisited(flag);
				}
			}
		}
	}
	
	//在进行遍历前,清除所有标记
	public void clearAllMark(){
		ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()){
			LinkedList<GraphListNode> ll = itr.next();
			for (GraphListNode gln: ll) {
				gln.setVisited(false);
			}
		}
		
	}
	
	public void DFS(int startVertex){
		clearAllMark();
		depthFirstSearch(startVertex);
	}
	
	//深度优先搜索
	public void depthFirstSearch(int startVertex){
		
		boolean isExisted = false;
		ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()) {
			//检测以startVertex为顶点的边链表是否存在
			LinkedList<GraphListNode> ll  = itr.next();
			if (ll.get(0).getVertex() == startVertex) {
				isExisted = true;
				//进行深度优先搜索
				Iterator<GraphListNode> it= ll.listIterator();
				
				//跳过第一个顶点并设置第一个顶点为以遍历
				System.out.print(startVertex+" ");
				GraphListNode gln = it.next();
				setMarkDouble(startVertex, true);
				
				while (it.hasNext()) {
					gln = it.next();
					//如果未访问,则进行深度搜索
					if (!gln.isVisited()) {
						depthFirstSearch(gln.getVertex());
						setMarkDouble(gln.getVertex(), true);
					}	

				}

				break;				
			}
		}
		if (!isExisted) {
			System.out.println(startVertex+" is not exists in this graph");
		}	
	}
	
	public void BFS(int startVertex){
		clearAllMark();
		breadthFirstSearch(startVertex);
	}
	
	//广度优先搜索
	public void breadthFirstSearch(int startVertex){
		boolean isExisted = false;
		ListIterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		//使用链表模仿队列
		LinkedList<Integer> store = new LinkedList<Integer>();
		isExisted = contains(startVertex);
		if (!isExisted) {
			System.out.println(startVertex+" is not exists in this graph");
		}
		//进行广度优先搜索
		else {
			
			//压入队列并设置为已遍历,初始化队列
			store.offer(startVertex);
			setMarkDouble(startVertex, true);
			
			while (!store.isEmpty()) {
				int current = store.poll();
				//打印当前顶点
				System.out.print(current+" ");
				//找出当前顶点对应的边链表
				itr = vertexList.listIterator();
				while(itr.hasNext()) {
					LinkedList<GraphListNode> ll  = itr.next();
					if (ll.get(0).getVertex() == current) {
						Iterator<GraphListNode> it = ll.listIterator();
						//跳过第一个
						it.next();
						while (it.hasNext()) {
							//将该顶点的所有相邻顶点压入队列
							GraphListNode gln = it.next();
							if (!gln.isVisited()) {
								store.offer(gln.getVertex());
								setMarkDouble(gln.getVertex(), true);
							}													
						}
					}
				}
			}		
		}		
	}
	
	
	//判断两个点是否联通
	//这里由于程序的限制,测试中一般只能测试是否直接相连
	public boolean isConnected(int src,int des){
		//递归终止条件
		
		Iterator<LinkedList<GraphListNode>> itr = vertexList.listIterator();
		while(itr.hasNext()) {
			//找到点U
			LinkedList<GraphListNode> ll = itr.next();
			if (ll.get(0).getVertex() == src) {
				Iterator<GraphListNode> it = ll.listIterator();
				//跳过它自身
				it.next();
				while (it.hasNext()) {
					src = http://www.mamicode.com/it.next().getVertex();>