1、图的基本概念
图是由结点集合及结点间的关系集合组成的一种数据结构。
图G的定义是:G=(V,E)
其中:
(1)V为边的集合,E为点的集合。
(2)(x,y)是一条双向通路,<x,y>是有方向的
2、图的实现
(1)、图的邻接结点类
public class AdjMWGraph {//邻接矩阵图类
static final int maxWeight = 10000;
private SeqList vertices; //存储结点
private int[][] edge;
private int numOfEdge; //边的个数
public AdjMWGraph(int maxV) {
vertices = new SeqList(maxV);
edge = new int[maxV][maxV];
for(int i=0;i<maxV;i++) {
for(int j=0;j<maxV;j++) {
if(i==j) edge[i][j] = 0;
else edge[i][j] = maxWeight;
}
}
numOfEdge = 0;
}
public int getVertices() {//返回结点个数
return vertices.size;
}
public void setVertices(SeqList vertices) {
this.vertices = vertices;
}
public int getNumOfEdge() {//返回边的个数
return numOfEdge;
}
public Object getValue(int v)throws Exception{
return vertices.getData(v);
}
public int getWeight(int v1,int v2) throws Exception {
if(v1<0||v1>=vertices.size||v2<0||v2>vertices.size)
throw new Exception("v1,v2出错");
return edge[v1][v2];
}
public void insertVertex(Object vertex) throws Exception {
vertices.insert(vertices.size,vertex);
}
public void insertEdge(int v1,int v2,int weight) throws Exception {
if(v1<0||v1>=vertices.size||v2<0||v2>vertices.size)
throw new Exception("v1,v2出错");
edge[v1][v2] = weight;
numOfEdge++;
}
public void deleteEdge(int v1,int v2) throws Exception {
if(v1<0||v1>=vertices.size||v2<0||v2>vertices.size)
throw new Exception("v1,v2出错");
if(edge[v1][v2] == maxWeight || v1 == v2) {
throw new Exception("该边不存在");
}
edge[v1][v2] = maxWeight;
numOfEdge--;
}
public int getFirstNeighbor(int v) throws Exception {
if(v<0||v>=vertices.size) {
throw new Exception("参数v错误");
}
for(int i=0;i<vertices.size;i++) {
if(edge[v][i]>0&&edge[v][i]<maxWeight) {
return i;
}
}
return -1;
}
public int getNextNeighbor(int v1,int v2) throws Exception {
if(v1<0||v1>=vertices.size||v2<0||v2>vertices.size)
throw new Exception("v1,v2出错");
for(int i=v2+1;i<vertices.size;i++) {
if(edge[v1][i]>0&&edge[v1][i]<maxWeight) {
return i;
}
}
return -1;
}
邻接结点创建:
class Visit{
public void print(Object obj) {
System.out.print(obj+" ");
}
}
class RowColWeight{
int row;
int col;
int weight;
public RowColWeight(int row,int col,int weight) {
this.row = row;
this.col = col;
this.weight = weight;
}
public static void createGraph(AdjMWGraph g,Object[] v,int n, RowColWeight[] rc,int e)
throws Exception{
for(int i=0;i<n;i++) {
g.insertVertex(v[i]);
}
for(int k=0;k<e;k++) {
g.insertEdge(rc[k].row, rc[k].col, rc[k].weight);
}
}
}
邻接结点测试:
public static void main(String[] args) {
int n=7,e=8;
AdjMWGraph g = new AdjMWGraph(n);
Character[] v = {
new Character('A'),new Character('B'),
new Character('C'),new Character('D'),
new Character('E'),new Character('F'),
new Character('G')
};
RowColWeight[] rc = {
new RowColWeight(0, 1, 10),new RowColWeight(0, 4, 20),
new RowColWeight(0, 6, 10),new RowColWeight(1, 3, 30),
new RowColWeight(2, 1, 40),new RowColWeight(3, 2, 50),
new RowColWeight(5, 1, 70),new RowColWeight(6, 5, 15)
};
try {
RowColWeight.createGraph(g, v, n, rc, e);
System.out.println("边"+g.getNumOfEdge());
System.out.println("结点"+g.getVertices());
Visit vs = new Visit();
g.depthFirstSearch(vs);
System.out.println();
g.broadFirstSearch(vs);
}catch (Exception e1) {
// TODO: handle exception
e1.printStackTrace();
}
}
}
图的深度与广度优先遍历
//连通树
public void depthFirstSearch(int v,boolean[] visited,Visit vs) throws Exception {
vs.print(getValue(v));
visited[v] = true;
int w = getFirstNeighbor(v);
while(w !=-1) {
if(!visited[w]) {
depthFirstSearch(w, visited, vs);
}
w = getNextNeighbor(v,w);
}
}
public void broadFirstSearch(int v,boolean[] visited,Visit vs) throws Exception {
int u,w;
SeqQueue queue = new SeqQueue();
vs.print(getValue(v));
visited[v] = true;
queue.append(v);
while(!queue.isEmpty()) {
u=(int) queue.delete();
w = getFirstNeighbor(u);
while(w != -1) {
if(!visited[w] ) {
vs.print(getValue(w));
visited[w] = true;
queue.append(w);
}
w = getNextNeighbor(u, w);
}
}
}
//非连通树
public void depthFirstSearch(Visit vs) throws Exception {
boolean visited[] = new boolean[getVertices()];
for(int i=0;i<getVertices();i++) {
if(!visited[i]) {
depthFirstSearch(i,visited,vs);
}
}
}
public void broadFirstSearch(Visit vs) throws Exception {
boolean visited[] = new boolean[getVertices()];
for(int i=0;i<getVertices();i++) {
if(!visited[i]) {
broadFirstSearch(i,visited,vs);
}
}
}
图:
遍历结果: