包括邻接链表、有向无向图、带权图、增删顶点和边、查找、连通、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(); */ } }
时间: 2024-10-28 08:39:42