用邻接表实现图的深度优先遍历、广度优先遍历、最短路径(无权图)


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;
}

}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值