数据结构☞图的表示
图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)
邻接矩阵
邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是row和col表示的是1.....n个点,相连为1,不相连为0
邻接表
- 邻接矩阵需要为每个顶点都分配n个边的空间,其实还有很多表都是不存在,会造成空间的一定损失。
- 邻接表的实现只关心存在的边,不关心不存在的边。因此没有空间浪费,邻接表由数组+链表组成
代码实现
定义接口
public interface Graph {
public void addEdge(int v, int w);
public boolean hasEdge(int v, int w);
public Iterable<Integer> adj(int v);
public void show();
public int n();
public int m();
}
邻接矩阵代码实现
public class DenseGraph implements Graph {
/**顶点数*/
private int n;
/**边数*/
private int m;
/**是否为有向图*/
private boolean directed;
/**图的具体数据*/
private boolean[][] g;
/**初始化没有任何边,定点之间的连接为false*/
public DenseGraph(int n, boolean directed) {
this.n = n;
this.directed = directed;
this.m = 0;
g = new boolean[n][n];
}
/**为图增加一条边**/
public void addEdge(int v,int w){
if(hasEdge(v,w)){
return;
}
g[v][w] = true;
if(!directed){
g[w][v] = true;
}
m++;
}
/**判断两个顶点之间有没有边**/
public boolean hasEdge(int v,int w){
assert v >= 0 && v < n;
assert w >= 0 && w < n;
return g[v][w];
}
/**返回图中一个顶点的所有邻边*/
public Iterable<Integer> adj(int v){
assert v >=0 && v < n;
Vector<Integer> vector = new Vector();
for(int i=0;i<n;i++){
if(g[v][i]){
vector.add(i);
}
}
return vector;
}
@Override
public void show() {
for(int i=0;i<n;i++){
for (int j=0;j<n;j++){
System.out.print(g[i][j]+"\t");
}
System.out.println();
}
}
@Override
public int n() {
return n;
}
@Override
public int m() {
return m;
}
}
邻接表代码实现
public class SparseGraph implements Graph{
/**顶点数*/
private int n;
/**边数*/
private int m;
/**是否为有向图*/
private boolean directed;
/**图的具体数据*/
private Vector<Integer>[] g;
public SparseGraph(int n,boolean directed) {
this.n = n;
this.m = 0;
this.directed = directed;
g = (Vector<Integer>[])new Vector[n];
for(int i=0;i<n;i++){
g[i] = new Vector<Integer>();
}
}
/**向图中增加一条边*/
public void addEdge(int v,int w){
if(hasEdge(v,w)){
return;
}
g[v].add(w);
if(v != w && !directed){
g[w].add(v);
}
}
/**验证图中是否有从v-w的边*/
public boolean hasEdge(int v,int w){
Vector<Integer> vector = g[v];
for(int i=0;i<vector.size();i++){
if(vector.elementAt(i)==w){
return true;
}
}
return false;
}
/**返回图中一个顶点的所有邻边*/
public Iterable<Integer> adj(int v){
assert v >=0 && v < n;
return g[v];
}
@Override
public void show() {
for(int i=0;i<n;i++){
System.out.print("vertex " + i + ":\t");
for(int j=0;j<g[i].size();j++){
System.out.print(g[i].elementAt(j)+"\t");
}
System.out.println();
}
}
/**返回定点数*/
@Override
public int n() {
return n;
}
/**返回边数*/
@Override
public int m() {
return m;
}
}