代码改变世界

图的邻接表实现

2012-07-11 22:49  coodoing  阅读(1339)  评论(0)    收藏  举报

  邻接表相关介绍 

     邻接表(Adjacency List)是图的一种链式存储方式。在邻接表中,对每个顶点(即表头节点)建立一个单链表,第i个单链表中节点表示依附于顶点vi 的边(对有向图而言,是以顶点vi为尾的弧)。所以在邻接表中,除了节点外,还有表头节点。

  数据结构定义如下

节点和表头节点的结构定义如下

image

具体数据结构定义如下:

ArcNode表示表节点,VNode表示头节点,ALGraph表示图

 

class 
ArcNode
 {
    int vex; //弧指向的顶点的位置
    ArcNode next; //指向下一条弧的指针
    String info; //该弧相关信息
    double weight; // 弧的权重
}
class 
VNode
{ 
    int vex; // 顶点节点信息 
     ArcNode firstNode; // 指向第一条依附该顶点的弧的指针 
}
class 
ALGraph
 {
    List<VNode> vertices;
    int vexNum; //顶点数量
    int arcNum; //弧数量
    int type; //类别:0无向图,1有向图
 
    public ALGraph() {
        vertices = new ArrayList<VNode>();
        vexNum = 0;             arcNum = 0;
        type = 0;//无向图
    }
}
拟建的图为:
image 
最后拟生成的邻接表为:

头结点为V1,对应的邻接表为: 2--->4--->null
头结点为V2,对应的邻接表为: 1--->3--->5--->null
头结点为V3,对应的邻接表为: 2--->4--->5--->null
头结点为V4,对应的邻接表为: 1--->3--->null
头结点为V5,对应的邻接表为: 2--->3--->null


代码如下:
   1: package Graph;
   2:  
   3: import java.util.ArrayList;
   4: import java.util.List;
   5:  
   6: // http://algs4.cs.princeton.edu/41undirected
   7: // jGraphT
   8: class ArcNode {
   9:     int vex; //弧指向的顶点的位置
  10:     ArcNode next; //指向下一条弧的指针
  11:     String info; //该弧相关信息
  12:     double weight; // 弧的权重
  13:  
  14:     public ArcNode(int vex, double weight) {
  15:         this(vex, null, "", weight);
  16:     }
  17:  
  18:     public ArcNode(int vex, ArcNode next, String info, double weight) {
  19:         this.vex = vex;
  20:         this.next = next;
  21:         this.info = info;
  22:         this.weight = weight;
  23:     }
  24: }
  25:  
  26: class VNode {
  27:     int vex; // 顶点节点信息
  28:     ArcNode firstNode; // 指向第一条依附该顶点的弧的指针
  29:  
  30:     public VNode(int vex) {
  31:         this(vex, null);
  32:     }
  33:  
  34:     public VNode(int vex, ArcNode firstNode) {
  35:         this.vex = vex;
  36:         this.firstNode = firstNode;
  37:     }
  38:  
  39:     public boolean equals(VNode node) {
  40:         if (vex == node.vex) {
  41:             return true;
  42:         }
  43:         return false;
  44:     }
  45: }
  46:  
  47: class ALGraph {
  48:     List<VNode> vertices;
  49:     int vexNum; //顶点数量
  50:     int arcNum; //弧数量
  51:     int type; //类别:0无向图,1有向图
  52:  
  53:     public ALGraph() {
  54:         vertices = new ArrayList<VNode>();
  55:         vexNum = 0;
  56:         arcNum = 0;
  57:         type = 0;//无向图
  58:     }
  59:  
  60:     public void createGraph(int[] vexs, int[][] arcs) {
  61:         //其实应该传进来参数是数组类型,这里为了操作简便,就简单的直接赋值
  62:         addVertex(1);
  63:         addVertex(2);
  64:         addVertex(3);
  65:         addVertex(4);
  66:         addVertex(5);
  67:  
  68:         addArc(1, 2);
  69:         addArc(1, 4);
  70:         addArc(2, 3);
  71:         addArc(2, 5);
  72:         addArc(3, 4);
  73:         addArc(3, 5);
  74:     }
  75:  
  76:     public void addVertex(int vex) {
  77:         VNode node = new VNode(vex);
  78:         if (!vertices.contains(node)) {
  79:             vertices.add(node);
  80:             vexNum++;
  81:         }
  82:     }
  83:  
  84:     public void addArc(int start, int end) {
  85:         addArc(start, end, 0);
  86:     }
  87:  
  88:     // 直接建立
  89:     private void addArc(int start, int end, double weight) {
  90:         VNode sNode = vertices.get(start - 1);
  91:         VNode eNode = vertices.get(end - 1);
  92:  
  93:         if(type==0)
  94:             addArcNext(eNode,sNode,weight);            
  95:         addArcNext(sNode,eNode,weight);        
  96:     }
  97:     
  98:     private void addArcNext(VNode sNode,VNode eNode, double weight)
  99:     {
 100:         ArcNode p = sNode.firstNode;            
 101:         ArcNode node = new ArcNode(eNode.vex, weight);
 102:         if (p == null) {
 103:             sNode.firstNode = node;             
 104:         } else {
 105:             ArcNode temp = sNode.firstNode;
 106:             while(true)
 107:             {
 108:                 //System.out.println("头结点后为:"+temp.vex);
 109:                 if (temp.next == null&&temp.vex!=node.vex)
 110:                 {
 111:                     temp.next = node;
 112:                     //System.out.println("next指针指向:"+temp.next.vex);
 113:                     break;                    
 114:                 }
 115:                 else if (temp.next!= null){
 116:                     temp = temp.next;
 117:                 }    
 118:             }
 119:         }
 120:         arcNum++;
 121:     }
 122:     
 123:     public void getAdjList(List<VNode> list)
 124:     {
 125:         VNode v;
 126:         for(int i=0;i<list.size();i++)
 127:         {
 128:             v = list.get(i);
 129:             getAdjNode(v);
 130:             System.out.println();            
 131:         }        
 132:     }
 133:     
 134:     private void getAdjNode(VNode v)
 135:     {
 136:         ArcNode p = v.firstNode;
 137:         System.out.print("头结点为V"+v.vex+",对应的邻接表为: ");
 138:         while (p != null) {
 139:             System.out.print(p.vex+"--->");
 140:             p = p.next;
 141:         }
 142:         System.out.print(p);
 143:     }
 144: }
 145:  
 146: public class GraphTest {
 147:     public static void main(String[] args) {
 148:         ALGraph graph = new ALGraph();
 149:         int[] vexs = new int[5];
 150:         int[][] arcs = new int[2][];
 151:         // 初始化图
 152:         graph.createGraph(vexs, arcs);
 153:         // 获取顶点的数目和边的数目
 154:         int arcNum = graph.arcNum;
 155:         if(graph.type == 0)
 156:             arcNum = graph.arcNum/2;
 157:         System.out.println("顶点的数目为: " + graph.vexNum + ";边的数目为: " + arcNum);
 158:         // 获取邻接表
 159:         graph.getAdjList(graph.vertices);
 160:     }
 161: }