一.邻接矩阵

图的邻接矩阵:用两个数组来表示图。一个一维数组存储图中的顶点信息,一个二维数组用来存储图中的边或弧的信息。

1. 主对角线全为0,因为不存在顶点到自身的值

2. 无向图的边数组是一个对称矩阵

3. 求顶点的度,如Vi的度,在邻接矩阵中第i行(第i列)的元素之和

4. 求顶点的邻接点,如vi的邻接点,扫描第i行,arc[i][j]为1就是邻接点

 

 

1.       主对角线全为0

2.       有向图的边数组矩阵不对称

3.       顶点Vi的入度,是第vi列的和,出度为vi行的和

 

1.       权来代替1

2.       无穷来代替0

代码实现

 

  1. #include<stdio.h> 
  2. #include<string.h>  
  3. #define MAXVEX 100 
  4. #define INFINITY 65535 
  5.  
  6. typedef char VertexType;//顶点类型  
  7. typedef int EdgeType;//边类型  
  8. typedef struct
  9.     VertexType vexs[MAXVEX];//顶点数组  
  10.     EdgeType arc[MAXVEX][MAXVEX];//边数组  
  11.     int numVertexes,numEdges;//顶点数和边数  
  12. }MGraph,*pMGraph; 
  13.  
  14. void createMGraph(pMGraph pMG){ 
  15.     int i,j,k,w; 
  16.     puts("Enter the numVertexes and numEdges:"); 
  17.     scanf("%d,%d",&(pMG->numVertexes),&(pMG->numEdges));//输入顶点数和边数  
  18.     puts("Enter the Vertexes:"); 
  19.     for(i=0;i<pMG->numVertexes;i++){//依次输入顶点信息  
  20.         puts("Enter the vexs one by one:"); 
  21.         scanf(&(pMG->vexs[i])); 
  22.     } 
  23.     for(i=0;i<pMG->numVertexes;i++){//初始化边数组为INFINITY  
  24.         for(j=0;j<pMG->numVertexes;j++){ 
  25.             pMG->arc[i][j] = INFINITY; 
  26.         } 
  27.     } 
  28.     for(k=0;k<pMG->numEdges;k++){//依次输入边(vi,vj)的i、j和权值  
  29.         puts("Enter the edges"); 
  30.         scanf("%d,%d,%d",&i,&j,&w); 
  31.         pMG->arc[i][j] = w; 
  32.         pMG->arc[i][j] = pMG->arc[j][i];//无向图是对称的,如果是有向图就省略这一步  
  33.     } 
  34. }  

 

 二.邻接表

 

数组与链表相结合的方式称为邻接表。图中的顶点用一个一维数组存储,该数组中的数据元素有一个data域存储顶点信息,一个firstedge存储指向第一个邻接点的指针,所有邻接点以单链表存储,无向图称为vi的边表,有向图称为以vi的弧尾(出度)的出边表

 

 

1.       求某顶点的度,查找这个顶点的边表中的结点个数

2.       求某顶点的所有邻接点,则对边表进行遍历即可

 

1.       求某顶点的入度,查找这个顶点的出边表即可

2.       但是我们无法很快求出入度,所以可以建立一个逆邻接表

 

1.       对于带权图,我们可以在边表结点中添加一个weight的数据域存储权值即可

代码实现

 

  1. #include<stdio.h> 
  2. #include<string.h> 
  3. #include<stdlib.h> 
  4. #define MAXVEX 100 
  5.  
  6.  
  7. typedef char VertexType; 
  8. typedef int EdgeType; 
  9. typedef struct EdgeNode{//边表结点  
  10.     int adjvex;//邻接点域,存储该顶点对应的下标  
  11.     EdgeType weight;//权值  
  12.     struct EdgeNode *next;//链域,指向下一个邻接点  
  13. }EdgeNode,*pEdgeNode; 
  14. typedef struct VertexNode{//顶点表结点  
  15.     VertexType data;//顶点域,存储顶点信息  
  16.     pEdgeNode firstedge;//指向边表的头指针  
  17. }VertextNode,*pVertextNode; 
  18. typedef struct {//顶点表 
  19.     VertexNode adjList[MAXVEX];//顶点表数组  
  20.     int numVertexes,numEdges;//存储图中的顶点数和边数  
  21. }GraphAdjList,*pGraphAdjList; 
  22.  
  23. void createALGraph(pGraphAdjList pGAL){ 
  24.     int i,j,k; 
  25.     pEdgeNode e; 
  26.     puts("Enter the numVertexes and numEdges:"); 
  27.     scanf("%d,%d",&(pGAL->numVertexes),&(pGAL->numEdges)); 
  28.     for(i=0;i<pGAL->numVertexes;i++){//输入顶点表信息  
  29.         scanf(&(pGAL->adjList[i].data));// 
  30.         pGAL->adjList[i].firstedge = NULL; 
  31.     } 
  32.     for(k=0;k<pGAL->numEdges;k++){ 
  33.         puts("Enter (Vi,Vj):");//输入边表信息  
  34.         scanf("%d,%d",&i,&j); 
  35.          
  36.         e = (pEdgeNode)malloc(sizeof(EdgeNode));// 采用头插法  
  37.         e->adjvex = j; 
  38.         e->next = pGAL->adjList[i].firstedge; 
  39.         pGAL->adjList[i].firstedge = e; 
  40.          
  41.         e = (pEdgeNode)malloc(sizeof(EdgeNode));//无向表,所以一条边对应两个顶点,要同时添加两个  
  42.         e->adjvex = i; 
  43.         e->next = pGAL->adjList[j].firstedge; 
  44.         pGAL->adjList[j].

三.十字链表(针对有向图)

 

将有向图的邻接表和逆邻接表结合起来

顶点表的结点结构变为

 

   Data

    Firstin

     Firstout

firstin表示入边表头指针,指向该结点的入边表中第一个结点

firstout表示出边表头指针,指向该结点的出边表第一个结点

边表结点的结构变为

   Tailvex

   Headvex

    Headlink

    Taillink

tailvex表示弧起点在顶点表中的下标

headvex表示弧终点在顶点表中的下标

headlink表示入边表指针域,指向终点相同的下一条边

taillink表示出边表指针域,指向起点相同的下一条边

 

1.       先完成出边表

2.       在完成入边表

3.       代码仍然使用头插法

四.邻接多重表(针对无向图)

边表结点结构为

Ivex

Ilink

Jvex

Jlink

ivexjvex是依附于一条边的两个顶点在顶点表中的下标。ilink指向依附于ivex的下一条边。jlink执行依附于jvex的下一条边

 

 五.边集数组

两个一维数组构成,一个存储顶点信息,另一个存储边的信息,这个边数组每个元素由起点下标、终点下标、权值组成。