import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class Graph {
/**关键字:图 邻接表 深度优先遍历 广度优先遍历 最短路径
* key words:Graph Adjacent-list depthFirstVisit breadthFirstVisit getCheapestPath
* 1.Graph is a collection of Vertex and Edge.
* When you want to implement 'Graph',you deal with two missions:how to implement 'Vertex' and 'Edge'
* a.Vertex:
* Type label-->Vertex's ID,to separate one Vertex from another,like 'A','B',or 0,1,2
* List<Edge> edgeList-->store edges that start with this Vertex.
* ...<output omit>
* b.Edge(as Inner class of Vertex):
* endVertex-->(begin,end),the outer class is 'begin',endVertex is 'end'
* ...<output omit>
* 2.In the following,we
* a.use ArrayList to store Vertices
* b.use 'char' as Vertex's ID
*/
private List<Vertex> vertices;
private int edgeCount;
private List<Vertex> depthFirstResult;
private List<Vertex> breadthFirstResult;
public void breadthFirstVisit(char beginLabel){
Vertex origin=this.getVertexByChar(beginLabel);
if(origin==null)return;
List<Vertex> queue=new LinkedList<Vertex>();
origin.setVisited(true);
queue.add(origin);
breadthFirstResult.add(origin);
Vertex curVertex=null;
while(!queue.isEmpty()){
curVertex=queue.remove(0);
while(curVertex.getFirstUnvisitedNeighbor()!=null){
Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();
tmpVertex.setVisited(true);
queue.add(tmpVertex);
breadthFirstResult.add(tmpVertex);
}
}
printVertexList(breadthFirstResult);
}
public void depthFirstVisit(char beginLabel){
Vertex origin=this.getVertexByChar(beginLabel);
if(origin==null)return;
Stack<Vertex> stack=new Stack<Vertex>();
origin.setVisited(true);
stack.push(origin);
depthFirstResult.add(origin);
Vertex curVertex=null;
while(!stack.isEmpty()){
curVertex=stack.peek();
Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();
if(tmpVertex!=null){
tmpVertex.setVisited(true);
depthFirstResult.add(tmpVertex);
stack.push(tmpVertex);
}else{
stack.pop();
}
}
printVertexList(depthFirstResult);
}
//getShortestPath.Base on breadthFirstVisit.the edge has no weight.
public double getShortestPath(char beginLabel,char endLabel,Stack<Vertex> stack){
resetVertices();
Vertex begin=this.getVertexByChar(beginLabel);
Vertex end=this.getVertexByChar(endLabel);
begin.setVisited(true);
List<Vertex> queue=new LinkedList<Vertex>();
queue.add(begin);
boolean done=false;
while(!done&&!queue.isEmpty()){
Vertex curVertex=queue.remove(0);
while(!done&&curVertex.getFirstUnvisitedNeighbor()!=null){
Vertex tmpVertex=curVertex.getFirstUnvisitedNeighbor();
tmpVertex.setVisited(true);
double tmpCost=curVertex.getCost()+1;
tmpVertex.setPreviousVertex(curVertex);
tmpVertex.setCost(tmpCost);
queue.add(tmpVertex);
if(tmpVertex.equals(end)){
done=true;
}
}
}
double pathLength=end.getCost();
//find the path.traverse back from end
while(end!=null){
stack.push(end);
end=end.getPreviousVertex();
}
return pathLength;
}
public boolean addEdge(char beginLabel,char endLabel,double weight){
int beginIndex=vertices.indexOf(new Vertex(beginLabel));
int endIndex=vertices.indexOf(new Vertex(endLabel));
Vertex beginVertex=vertices.get(beginIndex);
Vertex endVertex=vertices.get(endIndex);
boolean result=beginVertex.connect(endVertex,weight);
edgeCount++;
return result;
}
public boolean addEdge(char beginLabel,char endLabel){
return addEdge(beginLabel,endLabel,0);
}
public boolean addVertex(char label){
boolean result=false;
Vertex newVertex=new Vertex(label);
if(!vertices.contains(newVertex)){
vertices.add(newVertex);//reject duplicate vertex
result=true;
}
return result;
}
public void printVertexList(List<Vertex> list){
for(int i=0,len=list.size();i<len;i++){
Vertex vertex=list.get(i);
System.out.print(vertex.getLabel()+" ");
}
System.out.println();
}
public void resetVertices(){
for(int i=0,len=vertices.size();i<len;i++){
Vertex vertex=vertices.get(i);
vertex.setPreviousVertex(null);
vertex.setVisited(false);
vertex.setCost(0);
}
}
public Vertex getVertexByChar(char target){
Vertex vertex=null;
for(int i=0,len=vertices.size();i<len;i++){
vertex=vertices.get(i);
Character xx=vertex.getLabel();
if(xx.charValue()==target){
return vertex;
}
}
return vertex;
}
public Graph(){
vertices=new ArrayList<Vertex>();
edgeCount=0;
depthFirstResult=new ArrayList<Vertex>();
breadthFirstResult=new ArrayList<Vertex>();
}
public static void main(String[] args) {
Graph graph=createGapth();
graph.depthFirstVisit('7');//depthFirstVisit,start with '7'
graph.resetVertices();
graph.breadthFirstVisit('0');//breadthFirstVisit,start with '0'
//shortest path
Stack<Vertex> pathStack=new Stack<Vertex>();
//from '0' to '7'.
double pathLength=graph.getShortestPath('0','7',pathStack);
System.out.println(pathLength);
while(!pathStack.isEmpty()){
Vertex vertex=pathStack.pop();
System.out.print(vertex.getLabel()+" ");
}
//BasicGraphInterface<String> airMap=new UndirectedGraph<String>();
//airMap.
}
public static Graph createGapth(){
/*
0----1---2
| \ | |
| \ | |
| \| |
3 4 5
| /
| /
| /
6---7
the adjacent List is :
0-->4--3--1
1-->4--2--0
2-->5--1
3-->6--0
4-->6--1--0
5-->2
6-->7--4--3
7-->6
*/
Graph graph=new Graph();
graph.addVertex('0');
graph.addVertex('1');
graph.addVertex('2');
graph.addVertex('3');
graph.addVertex('4');
graph.addVertex('5');
graph.addVertex('6');
graph.addVertex('7');
graph.addEdge('0','4');
graph.addEdge('0','3');
graph.addEdge('0','1');
graph.addEdge('1','4');
graph.addEdge('1','2');
graph.addEdge('1','0');
graph.addEdge('2','5');
graph.addEdge('2','1');
graph.addEdge('3','6');
graph.addEdge('3','0');
graph.addEdge('4','6');
graph.addEdge('4','1');
graph.addEdge('4','0');
graph.addEdge('5','2');
graph.addEdge('6','7');
graph.addEdge('6','4');
graph.addEdge('6','3');
graph.addEdge('7','6');
return graph;
}
}
class Vertex{
private char label;
private List<Edge> edgeList;
private boolean isVisited;
private Vertex previousVertex;//use it in the method-'getShortestPath()'
private double cost;//the cost from beginning to this vertex
public Vertex(char label){
this.label=label;
edgeList=new ArrayList<Edge>();
isVisited=false;
previousVertex=null;
cost=0;
}
public boolean isVisited(){
return isVisited;
}
public void visit(){
System.out.println(this.label);
this.isVisited=true;
}
public void setPreviousVertex(Vertex vertex){
this.previousVertex=vertex;
}
public void setVisited(Boolean isVisited){
this.isVisited=isVisited;
}
public void setCost(double cost){
this.cost=cost;
}
public Vertex getFirstNeighbor(){
Vertex neighbor=this.edgeList.get(0).endVertex;
return neighbor;
}
public char getLabel(){
return this.label;
}
public double getCost(){
return this.cost;
}
public Vertex getPreviousVertex(){
return this.previousVertex;
}
public Vertex getFirstUnvisitedNeighbor(){
Vertex unVisitedNeighbor=null;
for(int i=0,len=edgeList.size();i<len;i++){
Vertex vertex=edgeList.get(i).endVertex;
if(!vertex.isVisited){
unVisitedNeighbor=vertex;
break;
}
}
return unVisitedNeighbor;
}
public boolean equals(Object object){
boolean result=false;
if(this==object)return true;
if(object instanceof Vertex){
Vertex otherVertex=(Vertex)object;
result=this.label==otherVertex.label;
}
return result;
}
public boolean connect(Vertex endVertex,double weight){
boolean result=false;//result=true if successful
if(!this.equals(endVertex)){//connections should occur in different Vertices
boolean isDuplicateEdge=false;
List<Edge> edgeList=this.edgeList;
if(edgeList.contains(endVertex)){
isDuplicateEdge=true;
}
if(!isDuplicateEdge){
//endVertex.previousVertex=this;
edgeList.add(new Edge(endVertex,weight));
result=true;
}
}
return result;
}
public boolean hasNeighbor(){
return !edgeList.isEmpty();
}
protected class Edge{
//A-->B,then the "outerClass" which invokes the method "getEndVertex"
//is "A",the "endVertex" is "B"
private Vertex endVertex;
private double weight;
protected Edge(Vertex endVertex,double weight){
this.endVertex=endVertex;
this.weight=weight;
}
protected Vertex getEndVertex(){
return endVertex;
}
protected double getWeight(){
return weight;
}
}
}
分享到:
相关推荐
总结以上,图的深度优先和广度优先遍历是基础的图遍历方法,关键路径和最短路径算法则用于解决实际问题,如项目管理、网络优化等。邻接表法作为一种高效的数据结构,有助于我们更好地操作和理解图的性质。
本篇文章将深入探讨两种主要的图遍历算法:深度优先遍历(DFS,Depth-First Search)和广度优先遍历(BFS,Breadth-First Search),并提供C语言的实现。 **深度优先遍历(DFS)** 深度优先遍历是一种递归的策略,...
本主题主要涵盖了三种关键概念:邻接矩阵、邻接表以及图的两种遍历方法——深度优先搜索(DFS)和广度优先搜索(BFS)。 首先,邻接矩阵是一种表示图的数据结构,它是一个二维数组,其中的每个元素代表图中对应节点...
遍历无向图有多种方式,包括深度优先搜索(DFS)和广度优先搜索(BFS)。DFS常使用栈来实现,从一个顶点出发,沿着边访问未访问过的顶点;BFS则用队列,先访问距离起点近的顶点。"quene.h"可能是定义队列的头文件,...
深度优先遍历(DFS, Depth First Search)和广度优先遍历(BFS, Breadth First Search)是图论中两种重要的遍历算法,用于访问图的所有顶点。这两种方法各有特点,适用于不同的场景。 深度优先遍历是一种递归的搜索策略...
在这个主题中,我们将深入探讨图的深度遍历(Depth-First Search, DFS)和广度遍历(Breadth-First Search, BFS)这两种遍历算法,以及它们在数据结构基本实验中的应用。 **1. 图的基本概念** 图由顶点(Vertex)...
然而,对于稀疏图来说,邻接矩阵会占用大量的空间,这时可能需要考虑使用邻接表等其他存储方式。 图的遍历算法是图论中的基础概念之一,深度优先遍历和广度优先遍历各有优缺点,具体选择哪种遍历方法取决于实际应用...
根据给定文件的信息,我们可以详细地探讨一下“图的广度优先遍历算法”这一主题。广度优先遍历(Breadth-First Search,简称 BFS)是一种用于遍历或搜索树或图的算法。其特点是先访问离起始节点距离较近的所有节点,...
图的遍历算法可以使用邻接表法或邻接矩阵法实现。邻接表法是用一个数组来存储图的边信息,邻接矩阵法是用一个矩阵来存储图的边信息。不同的算法有不同的实现方式和性能分析结果。 Dijkstra算法 Dijkstra算法是一种...
广度优先遍历是一种基础的图和树遍历算法,它按照层次顺序访问节点,适用于多种问题,如最短路径、环路检测和层次遍历等。通过队列和颜色标记的数据结构,BFS能有效地处理这些问题,并且在许多情况下优于深度优先...
2. **实现图的广度优先遍历算法** 3. **分析示例输入与输出** 4. **代码解析** ### 1. 理解图的广度优先遍历(BFS) **定义:** - 广度优先遍历是一种用于图的搜索算法。它按照层次顺序遍历图的所有顶点,即从根节点...
以任意结点 v 为起点,实现上述图的深度优先和广度优先遍历算法。 3、最小生成树的算法实现 利用普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法求上图的最小生成树,算法实现 代码必须有注释。 4、最短路径的算法实现 ...
图遍历主要有两种方法:深度优先搜索(DFS,Depth-First Search)和广度优先搜索(BFS,Breadth-First Search)。这两种算法在处理网络数据结构、树结构、搜索问题以及解决许多其他计算问题时都扮演着核心角色。 ##...
BFS特别适用于寻找最短路径问题,比如在无权图中寻找两个节点间的最短路径。在C语言中,我们需要创建一个队列结构,并实现入队、出队操作来实现BFS。 在实际编程中,图通常使用邻接矩阵或邻接表来表示。邻接矩阵是...
这里我们将详细讨论图的基本概念、遍历的重要性以及两种主要的遍历策略:深度优先搜索(DFS)和广度优先搜索(BFS)。 首先,我们需要理解图的基本构成。一个图由顶点(或节点)和边组成,边表示顶点之间的关系。图...
在这个"zsrf.rar_图的遍历c语言"压缩包中,包含的"zsrf.doc"文档很可能是对C语言实现图的深度优先遍历(DFS, Depth First Search)和广度优先遍历(BFS, Breadth First Search)的实验代码及其分析报告。 1. **深度...
图的遍历可以用深度优先遍历(DFS)和广度优先遍历(BFS)两种方式。深度优先遍历使用栈,时间复杂度为O(|V|+|E|)。广度优先遍历使用队列,时间复杂度为O(|V|+|E|)。 图的连通性 图的连通性可以用深度优先遍历或...
DFS适用于无权图的遍历,但不保证找到最短路径;BFS在所有节点距离起点相同的情况下能找到最短路径,但不适用于带权重的图;Dijkstra算法则是解决带权重图中最短路径问题的经典算法,它可以找到从源节点到其他所有...
//-----------------------图的邻接表存储表示------------------------ typedef struct ArcNode { int adjvex; //该弧所指向的顶点的位置 struct ArcNode *nextarc; //指向下一条弧的指针 InfoType *info; //该...
通过对深度优先搜索、广度优先搜索及其生成树的介绍,我们可以看出这两种搜索方法在图遍历方面各有优势。DFS更适用于寻找特定路径或探索所有可能路径的问题,而BFS则更适合于寻找最短路径或分层遍历的问题。通过这两...