简单起见,顶点卫星数据类型为char,弧没有额外信息。
邻接矩阵:
import java.util.*;
public class GraphMatrix {
public static final int DEFAULTSIZE = 20;//默认规模
private int size;//规模
private Vertex[] vertexArray;//顶点数组
private int[][] adjMatrix;//邻接矩阵
private int itemNumber;//顶点数
public GraphMatrix()
{
size = DEFAULTSIZE;
vertexArray = new Vertex[size];
adjMatrix = new int[size][size];
itemNumber = 0;
}
public GraphMatrix(int size)
{
this.size = size;
this.vertexArray = new Vertex[size];
adjMatrix = new int[size][size];
itemNumber = 0;
}
public boolean isEmpty()
{
return (itemNumber == 0 );
}
//增加顶点
public void addVertex(char label)
{
if(size > 0)
{
Vertex newVertex = new Vertex(label);
for(int i=0;i<size;++i)
if(vertexArray[i] == null)
{
vertexArray[i] = newVertex;
++itemNumber;
return;
}
}
}
//添加边
public void addArc(int i,int j)
{
if(size > 0)
adjMatrix[j][i]=adjMatrix[i][j] = 1;
}
//广度优先搜索
public void bfs()
{
if(!isEmpty())
{
Queue<Integer> queue = new LinkedList<Integer>();
queue.offer(0);
while(!queue.isEmpty())
{
int cur = queue.poll().intValue();
if(vertexArray[cur].visited == false)
{
System.out.print(vertexArray[cur].label);
vertexArray[cur].visited = true;
}
for(int j=0;j<itemNumber;++j)
if(adjMatrix[cur][j] == 1 && vertexArray[j].visited == false)
queue.offer(j);
}
for(int i=0;i<itemNumber;++i)
vertexArray[i].visited = false;
}
}
//深度优先搜索,未递归。
public void dfs()
{
if(itemNumber > 0)
{
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
while(!stack.empty())
{
int cur = stack.peek().intValue();
if(vertexArray[cur].visited == false)
{
System.out.print(vertexArray[cur].label);
vertexArray[cur].visited = true;
}
int j=0;
for(;j<itemNumber;++j)
if(adjMatrix[cur][j] == 1 && vertexArray[j].visited == false)
{
stack.push(j);
break;
}
if(j == itemNumber)
stack.pop();
}
for(int i=0;i<itemNumber;++i)
vertexArray[i].visited = false;
}
}
//顶点类型
private class Vertex
{
public char label;
public boolean visited;//顶点访问标记
public Vertex(char label)
{
this.label = label;
this.visited = false;
}
}
}
邻接表:(注:有向图)
package dataStructure;
import java.util.*;
/**
* @author lcq
*邻接表
*/
public class GraphList {
private ArrayList<Vertex> vertexList;//动态数组存储顶点
public GraphList()
{
vertexList = new ArrayList<Vertex>();
}
//广度优先搜索
public void bfs()
{
if(vertexList.isEmpty())
return;
Queue<Vertex> queue = new LinkedList<Vertex>();
queue.offer(vertexList.get(0));
while(!queue.isEmpty())
{
//取出队列头部元素,访问之。然后,将其所有未被访问过的邻接点入队列。
Vertex cur = queue.poll();
if(cur.visited == false)
{
System.out.print(cur.value);
cur.visited = true;
}
Arc arc = cur.first;
while(arc != null)
{
if(arc.vertex.visited == false)
queue.offer(arc.vertex);
arc = arc.next;
}
}
System.out.println();
reset();
}
//深度优先搜索
public void dfs()
{
if(vertexList.isEmpty())
return;
Vertex cur = vertexList.get(0);
System.out.print(cur.value);
cur.visited = true;
Stack<Arc> stack = new Stack<Arc>();
Arc arc = cur.first;
if(arc == null)
return;
stack.push(arc);//将 第一个顶点的第一条非空弧入栈。
while(!stack.empty())
{
arc = stack.peek();
cur = arc.vertex;//当前弧对应顶点即待访问顶点
if(!cur.visited)
{
System.out.print(cur.value);
cur.visited = true;
}
arc = cur.first;//已访问顶点的第一条弧
while(arc != null)//寻找未被访问的弧
{
if(!arc.vertex.visited)
{
stack.push(arc);
break;
}else
arc = arc.next;
}
while(arc == null)//未找到
{
if(!stack.empty())
{
arc = stack.pop().next;
while(arc != null)
{
if(!arc.vertex.visited)
{
stack.push(arc);
break;
}else
arc = arc.next;
}
}else
break;
}
}
System.out.println();
reset();
}
//dfs利用visit数组和low数组来输出所有的强连通分量。
//visit[v]:顶点v在dfs中访问的次序。
//low[v]:顶点v能追溯到的最早的访问次序。
//stack:存储dfs过程中访问到的顶点。
public void stronglyConnected()
{
int[] visit = new int[vertexList.size()];
int[] low = new int[vertexList.size()];
Stack<Vertex> stack = new Stack<Vertex>();
int[] count = new int[1];
for(Vertex vertex : vertexList)
if(!vertex.visited)
stronglyConnectedNode(vertex,visit,low,stack,count);
reset();
}
private void stronglyConnectedNode(Vertex vertex,int[] visit,int[] low,Stack<Vertex> stack,int[] count)
{
if(vertex.visited)
return;
int index = vertexList.indexOf(vertex);
stack.push(vertex);
visit[index] = ++count[0];
low[index] = visit[index];
vertex.visited = true;
Arc curArc = vertex.first;
while(curArc != null)
{
int i = vertexList.indexOf(curArc.vertex);
if(curArc.vertex.visited)
{
if(visit[i] < low[index])
low[index] = visit[i];
}
else
{
stronglyConnectedNode(curArc.vertex,visit,low,stack,count);
if(low[index] > low[i])
low[index] = low[i];
}
curArc = curArc.next;
}
//若vertex对应的low和visit相等,则弹出stack中vertex以上的顶点(即成一强连通分量)
if(low[index] == visit[index])
{
while(!stack.empty())
{
Vertex cur = stack.pop();
System.out.print(cur.value);
if(cur == vertex)
break;
}
System.out.println();
}
}
//添加定点对。
public void add(char ch1,char ch2)
{
if(indexOfChar(ch1) == -1)
vertexList.add(new Vertex(ch1));
if(indexOfChar(ch2) == -1)
vertexList.add(new Vertex(ch2));
int index1 = indexOfChar(ch1);
int index2 = indexOfChar(ch2);
Arc arc1 = new Arc(vertexList.get(index1));
Arc arc2 = new Arc(vertexList.get(index2));
addVertex(ch1,arc2);
// addVertex(ch2,arc1);
}
private void addVertex(char ch,Arc arc)
{
int index = indexOfChar(ch);
if(index == -1)
{
vertexList.add(new Vertex(ch));
index = vertexList.size()-1;
}
Vertex vertex = vertexList.get(index);
if(vertex.first == null)
vertex.first = arc;
else
{
Arc cur = vertex.first;
while(cur.next != null)
{
if(cur.vertex.equals(arc.vertex))
return;
cur = cur.next;
}
cur.next = arc;
}
}
//返回字符ch在顶点列表中的位置。
private int indexOfChar(char ch)
{
for(int i=0;i<vertexList.size();++i)
if(vertexList.get(i).value == ch)
return i;
return -1;
}
//复位,将所有顶点的visited属性置为false.
private void reset()
{
Iterator<Vertex> iter = vertexList.iterator();
while(iter.hasNext())
iter.next().visited = false;
}
private class Vertex
{
public char value;
public Arc first;
public boolean visited;
public Vertex(char value)
{
this.value = value;
first = null;
this.visited = false;
}
public boolean equals(Vertex vertex)
{
return this.value == vertex.value;
}
}
private class Arc
{
public Vertex vertex;
public Arc next;
public int data;
public Arc(Vertex vertex)
{
this.vertex = vertex;
this.next = null;
this.data = 0;
}
public Arc(Vertex vertex ,int data)
{
this.vertex = vertex;
this.next = null;
this.data = data;
}
}
}