首页 > 其他 > 详细

图的所有简单算法实现

时间:2014-06-11 06:23:46      阅读:507      评论:0      收藏:0      [点我收藏+]

包括邻接链表、有向无向图、带权图、增删顶点和边、查找、连通、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 = it.next().getVertex();
					if (src == des) {
						return true;
					}
					//恢复迭代器
					itr = vertexList.listIterator();						
				}				
			}
		}
		return false;
		
	}
	
	//打印邻接链表
	public void printAllLinkedlist(){
		for (LinkedList<GraphListNode> ll : vertexList) {
			for (GraphListNode gln : ll) {
				//权重为0则不打印
				if (gln.getWeight() == 0) {
					System.out.print(gln.getVertex()+" ");
				}
				else{
					System.out.print(gln.getVertex()+"("+gln.getWeight()+") ");
				}				
			}
			System.out.println();
		}
	}
	
	/**
	 * Kuruskal算法:根据边找出最小生成树
	 * Prim算法:根据点找出最下生成树
	 * Dijkstra算法:每次处理一个顶点,最终得到从某一顶点到所有其他顶点的最短路径
	 * 省略
	 * */	
	
	public static void main(String[] args) {
		//建立一个无向图
/*		AdjacencyListGraph alg = new AdjacencyListGraph();

		alg.addEdgeDouble(1,3);
		alg.addEdgeDouble(1,5);
		alg.addEdgeDouble(2,3);
		alg.addEdgeDouble(2,6);
		alg.addEdgeDouble(3,4);
		alg.addEdgeDouble(3,6);
		alg.addEdgeDouble(5,6);
		alg.addEdgeDouble(7, 4);

		
		alg.printAllLinkedlist();
		System.out.println("--------------");
	    alg.deleteVertexDouble(1);
		alg.printAllLinkedlist();
		System.out.println("--------------");
		alg.addVertexSingle(1);
		alg.addEdgeDouble(1, 3);
		alg.addEdgeDouble(1, 5);
		alg.printAllLinkedlist();
		System.out.println("--------------");
		
		alg.DFS(1);
		System.out.println("\n--------------");
		alg.BFS(1);
	
		
		//System.out.println(alg.isConnected(1, 4));
		
		//增加有向边,并设置权重
		alg.addEdgeSingle(1,2,10);
		alg.addEdgeSingle(1,3,3);
		alg.addEdgeSingle(1,4,20);
		alg.addEdgeSingle(3,2,2);
		alg.addEdgeSingle(2,4,5);
		alg.addEdgeSingle(3,5,15);
		alg.addEdgeSingle(4,5,11);
		alg.printAllLinkedlist();
*/			
		
		
	}
}


图的所有简单算法实现,布布扣,bubuko.com

图的所有简单算法实现

原文:http://blog.csdn.net/wanghao109/article/details/29360337

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!