图的存储结构

一般存储图的方式有两种:一是用邻接矩阵表示,二是用邻接链表。

所谓用邻接矩阵,是用一个二维数组存储,边使用矩阵来构建模型,这使得每一个顶点和其它顶点之间都有边的有无 的 表示的机会。若有边,则他们交点 为1 ,否则为0。当然,如果是一副边有权值的图,交点存储的是他们边的权值。

1、首先收一下无向图的存储:

 

无向图的边的矩阵一定是一个对称矩阵,因为无向图只关心边是否存在,而不关心方向,V0和V1有边,那么V1和V0也有边。

因为这里不研究有圈图,所以主对角线都是0,输入V0和V1边的关系后,就不必输入V1和V0的关系了。

图解如下:

 

[cpp] view plain copy

  1. 实现代码如下:  

[cpp] view plain copy

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. #define MAX_VERTEX 4  //4个顶点的图  
  5.   
  6. typedef char DataType;  
  7.   
  8. typedef struct  
  9. {  
  10.     DataType vertexArr[MAX_VERTEX];       //顶点元素数组     
  11.     int edgeArr[MAX_VERTEX][ MAX_VERTEX]; //边矩阵二维数组   
  12. }ArrayGraph;  
  13.   
  14. void ArrayGraph_init(ArrayGraph *pGraph);  
  15. void ArrayGraph_create(ArrayGraph *pGraph);  
  16. void ArrayGraph_show(ArrayGraph *pGraph);  
  17.   
  18. int main()  
  19. {  
  20.     ArrayGraph g;  
  21.     ArrayGraph_init(&g);       //初始化图   
  22.     ArrayGraph_create(&g);     //创建图   
  23.     ArrayGraph_show(&g);       //打印图   
  24.   
  25.   
  26.   
  27.     return 0;  
  28. }  
  29.   
  30. //初始化为一个无圈图 ,也就是边矩阵中,主对角线元素都是0   
  31. void ArrayGraph_init(ArrayGraph *pGraph)  
  32. {  
  33.       
  34.     for (int i = 0; i < MAX_VERTEX; i++)  
  35.   
  36.         pGraph->edgeArr[i][i] = 0;  
  37.   
  38. }  
  39.   
  40. //输入一个图   
  41. void ArrayGraph_create(ArrayGraph *pGraph)  
  42. {  
  43.       
  44.   
  45.     for (int i = 0; i < MAX_VERTEX; ++i)    //填充顶点数组,也就是输入顶点元素   
  46.     {  
  47.         printf("输入第%d个顶点值\n",i+1);  
  48.           
  49.         scanf(" %c",&(pGraph->vertexArr[i]));   
  50.   
  51.     }  
  52.   
  53.     for (int j = 0; j <MAX_VERTEX; ++j)   //填充边关系   
  54.     {  
  55.         for (int i = j+1; i < MAX_VERTEX; ++i)  
  56.         {  
  57.               
  58.             printf("若元素%c和%c有边,则输入1,否则输入0\t",pGraph->vertexArr[j],pGraph->vertexArr[i]);  
  59.               
  60.             scanf("%d",&( pGraph->edgeArr[j][i]));  
  61.             pGraph->edgeArr[i][j] = pGraph->edgeArr[j][i];     //对称   
  62.         }  
  63.     }  
  64.   
  65.   
  66.   
  67. }  
  68.   
  69. void ArrayGraph_show(ArrayGraph *pGraph)  
  70. {  
  71.   
  72.   
  73.     printf("\n\n顶点元素如下\n");  
  74.     for (int i = 0; i < MAX_VERTEX; ++i)  
  75.     {  
  76.           
  77.         printf("%-5c", pGraph->vertexArr[i]);  
  78.     }  
  79.     printf("\n\n");  
  80.   
  81.   
  82.       
  83.     puts("边矩阵如下\n\n");   
  84.     printf("%-2c",' ');  
  85.     for(int i=0;i<MAX_VERTEX;++i)  
  86.       printf("%-5c",pGraph->vertexArr[i]);  
  87.     putchar('\n');    
  88.       
  89.       
  90.       
  91.     for (int j = 0; j <MAX_VERTEX; ++j)  
  92.     {  
  93.         printf("%-2c",pGraph->vertexArr[j]);  
  94.         for (int i = 0; i < MAX_VERTEX; ++i)  
  95.         {  
  96.             printf("%-5d",pGraph->edgeArr[i][j]);  
  97.   
  98.         }  
  99.         putchar('\n');  
  100.     }  
  101.       
  102.     printf("\n\n");  
  103. }  


2、有向图的邻接矩阵存储:

 

 

使用邻接矩阵呢存储时,有向图和无向图的区别在与 边和弧矩阵的差别。因为弧是有方向的,所以我们 以对角线为界,将矩阵划分为2个区域:

左下区域表示出弧标记区域,坐上区域代表入弧标记区域

如  若代表弧的矩阵为arcArr

 

 arcArr[V2][V3] 为1,且在出弧标记区域,则说明 V3<------V2

 arcArr[V3][V2] 为0,且在入弧标记区域,则说明 V2---\--->V3


代码实现如下:

 

[cpp] view plain copy

  1. #include<stdio.h>  
  2.   
  3. #define  MAX_VERTEX  4  
  4.   
  5. typedef char DataType;                 //图中元素的目标数据类型   
  6.   
  7.   
  8. typedef struct      
  9. {                    
  10.     DataType vertexArr[MAX_VERTEX];        //顶点元素数组   
  11.   
  12.     int arcArr[MAX_VERTEX][MAX_VERTEX];   //弧矩阵二维数组   
  13.       
  14.   
  15. }ArrayGraph;  
  16.   
  17. void ArrayGraph_init(ArrayGraph *pGraph);  
  18. void ArrayGraph_create(ArrayGraph *pGraph);  
  19. void ArrayGraph_show(ArrayGraph *pGraph);  
  20.   
  21.   
  22.   
  23. int main()  
  24. {  
  25.     ArrayGraph g;  
  26.     ArrayGraph_init(&g);  
  27.     ArrayGraph_create(&g);  
  28.     ArrayGraph_show(&g);  
  29.   
  30.   
  31.   
  32.     return 0;  
  33. }  
  34.   
  35.   
  36.   
  37. //初始化为一个无圈图 ,也就是弧矩阵中,主对角线元素都是0   
  38. void ArrayGraph_init(ArrayGraph *pGraph)  
  39. {  
  40.       
  41.     for (int i = 0; i < MAX_VERTEX; i++)  
  42.   
  43.         pGraph->arcArr[i][i] = 0;  
  44.   
  45. }  
  46.   
  47.   
  48. void ArrayGraph_create(ArrayGraph *pGraph)  
  49. {  
  50.       
  51.   
  52.     for (int i = 0; i < MAX_VERTEX; ++i)  //填充顶点数组  
  53.     {  
  54.         printf("输入第%d个顶点值\n",i+1);  
  55.           
  56.         scanf(" %c",&(pGraph->vertexArr[i]));   
  57.   
  58.     }  
  59.   
  60.     for (int j = 0; j <MAX_VERTEX; ++j)   //填充边关系   
  61.     {  
  62.         for (int i = j+1; i < MAX_VERTEX; ++i)  
  63.         {  
  64.               
  65.             printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",pGraph->vertexArr[i],pGraph->vertexArr[j]);  
  66.             scanf("%d",&( pGraph->arcArr[j][i]));  
  67.               
  68.             printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",pGraph->vertexArr[j],pGraph->vertexArr[i]);  
  69.             scanf("%d",&( pGraph->arcArr[i][j]));  
  70.         }  
  71.     }  
  72.   
  73.   
  74.   
  75.   
  76.   
  77.   
  78. }  
  79.   
  80.   
  81. void ArrayGraph_show(ArrayGraph *pGraph)  
  82. {  
  83.   
  84.   
  85.     printf("\n\n顶点元素如下\n");  
  86.     for (int i = 0; i < MAX_VERTEX; ++i)  
  87.     {  
  88.           
  89.         printf("%-5c", pGraph->vertexArr[i]);  
  90.     }  
  91.     printf("\n\n");  
  92.   
  93.   
  94.       
  95.     puts("弧矩阵如下\n\n");   
  96.     printf("%-2c",' ');  
  97.     for(int i=0;i<MAX_VERTEX;++i)  
  98.       printf("%-5c",pGraph->vertexArr[i]);  
  99.     putchar('\n');    
  100.       
  101.       
  102.       
  103.     for (int j = 0; j <MAX_VERTEX; ++j)  
  104.     {  
  105.         printf("%-2c",pGraph->vertexArr[j]);  
  106.         for (int i = 0; i < MAX_VERTEX; ++i)  
  107.         {  
  108.             printf("%-5d",pGraph->arcArr[i][j]);  
  109.   
  110.         }  
  111.         putchar('\n');  
  112.     }  
  113.     putchar('\n');    
  114. }  


3、有权值无向图(无向网)的邻接矩阵存储:

 

 

无向网的边是有权值的,这个值可以是任何一个合法的值,什么样的值是合法的呢?这需要根据图的具体用途来定。所以,我们不能用简单的0,1来代表边。

如果2个顶点无关联,他们也不能用0表示,因为0也可能是一个合法的wieght值。可有类比一下:如何地球上2个地方之间不可互通,那么他们之间的车程费是不是无穷大呢?

所以,我们来要根据图权值类型定义一个相应类型的最大值,来代表2个顶点之间不关联。

同样用一个例子。

 V0 V1之间的权值为12

V0 V2之间的权值为1

V0 V3之间的权值为5

V2 V3之间的权值为7

代码实现如下:

 

[cpp] view plain copy

  1. #include<stdio.h>  
  2.   
  3.   
  4. #define MAX_VERTEX 4       
  5.   
  6. #define INFINITY  65535  
  7.   
  8. typedef char DataType;     //存储的元素类型   
  9. typedef int WeightType;    //权值的类型   
  10.   
  11. typedef struct  
  12. {  
  13.     DataType vertexArr[MAX_VERTEX];             //存储顶点的数组   
  14.   
  15.     WeightType edgeArr[MAX_VERTEX][MAX_VERTEX]; //存储边的二维数组   
  16.   
  17. }UArrayNet;     //数据结构类型:无向网   
  18.   
  19.   
  20. void UArrayNet_init(UArrayNet*pGraph);  
  21. void UArrayNet_create(UArrayNet*pGraph);  
  22. void UArrayNet_show(UArrayNet *pGraph);  
  23.   
  24. int main()  
  25. {  
  26.     UArrayNet net;  
  27.     UArrayNet_init(&net);  
  28.   
  29.     UArrayNet_create(&net);  
  30.     UArrayNet_show(&net);  
  31.   
  32.   
  33.   
  34.     return 0;  
  35. }  
  36.   
  37. void UArrayNet_init(UArrayNet*pGraph)  
  38. {  
  39.     for (int i = 0; i < MAX_VERTEX; ++i)  
  40.     {  
  41.         pGraph->edgeArr[i][i] = INFINITY;  
  42.     }  
  43.   
  44.   
  45. }  
  46.   
  47.   
  48. void UArrayNet_create(UArrayNet*pGraph)  
  49. {  
  50.     for (int i = 0; i < MAX_VERTEX; ++i)  //填充顶点数组  
  51.     {  
  52.         printf("输入第%d个顶点值\n", i + 1);  
  53.   
  54.         scanf(" %c", &(pGraph->vertexArr[i]));  
  55.   
  56.     }  
  57.   
  58.     for (int j = 0; j <MAX_VERTEX; ++j)   //填充边关系   
  59.     {  
  60.         for (int i = j + 1; i < MAX_VERTEX; ++i)  
  61.         {  
  62.   
  63.             printf("若元素%c和%c有边,则输入权值,否则输入无效值%d\t", pGraph->vertexArr[j], pGraph->vertexArr[i], INFINITY);  
  64.   
  65.             scanf("%d", &(pGraph->edgeArr[j][i]));  
  66.             pGraph->edgeArr[i][j] = pGraph->edgeArr[j][i];     //对称   
  67.         }  
  68.     }  
  69.   
  70.   
  71. }  
  72.   
  73. void UArrayNet_show(UArrayNet *pGraph)  
  74. {  
  75.   
  76.   
  77.     printf("\n\n顶点元素如下\n");  
  78.     for (int i = 0; i < MAX_VERTEX; ++i)  
  79.     {  
  80.   
  81.         printf("%-5c", pGraph->vertexArr[i]);  
  82.     }  
  83.     printf("\n\n");  
  84.   
  85.   
  86.   
  87.     puts("边矩阵如下");  
  88.     printf("%-2c", ' ');  
  89.     for (int i = 0; i<MAX_VERTEX; ++i)  
  90.         printf("%-5c", pGraph->vertexArr[i]);  
  91.     putchar('\n');  
  92.   
  93.   
  94.   
  95.     for (int j = 0; j <MAX_VERTEX; ++j)  
  96.     {  
  97.         printf("%-2c", pGraph->vertexArr[j]);  
  98.         for (int i = 0; i < MAX_VERTEX; ++i)  
  99.         {  
  100.             if(pGraph->edgeArr[i][j]==INFINITY)  
  101.             {  
  102.                 printf("%-5c", '#');  
  103.                   
  104.             }   
  105.             else  
  106.                 printf("%-5d", pGraph->edgeArr[i][j]);  
  107.   
  108.         }  
  109.         putchar('\n');  
  110.     }  
  111. }  


4、有向网邻接矩阵存储

 

有向网的实现与无向网思路一致,就不重复累赘了,直接上代码吧。

 

[cpp] view plain copy

  1. #include<stdio.h>  
  2.   
  3.   
  4. #define MAX_VERTEX 4       
  5.   
  6. #define INFINITY  65535  
  7.   
  8. typedef char DataType;     //存储的元素类型   
  9. typedef int WeightType;    //权值的类型   
  10.   
  11. typedef struct  
  12. {  
  13.     DataType vertexArr[MAX_VERTEX];             //存储顶点的数组   
  14.   
  15.     WeightType arcArr[MAX_VERTEX][MAX_VERTEX]; //存储边的二维数组   
  16.   
  17. }UArrayNet;     //数据结构类型:无向网   
  18.   
  19.   
  20. void UArrayNet_init(UArrayNet*pGraph);  
  21. void UArrayNet_create(UArrayNet*pGraph);  
  22. void UArrayNet_show(UArrayNet *pGraph);  
  23.   
  24. int main()  
  25. {  
  26.     UArrayNet net;  
  27.     UArrayNet_init(&net);  
  28.   
  29.     UArrayNet_create(&net);  
  30.     UArrayNet_show(&net);  
  31.   
  32.   
  33.   
  34.     return 0;  
  35. }  
  36.   
  37. void UArrayNet_init(UArrayNet*pGraph)  
  38. {  
  39.     for (int i = 0; i < MAX_VERTEX; ++i)  
  40.     {  
  41.         pGraph->arcArr[i][i] = INFINITY;  
  42.     }  
  43.   
  44.   
  45. }  
  46.   
  47.   
  48. void UArrayNet_create(UArrayNet*pGraph)  
  49. {  
  50.     for (int i = 0; i < MAX_VERTEX; ++i)  //填充顶点数组  
  51.     {  
  52.         printf("输入第%d个顶点值\n", i + 1);  
  53.   
  54.         scanf(" %c", &(pGraph->vertexArr[i]));  
  55.   
  56.     }  
  57.   
  58.     for (int j = 0; j <MAX_VERTEX; ++j)   //填充边关系   
  59.     {  
  60.         for (int i = j + 1; i < MAX_VERTEX; ++i)  
  61.         {  
  62.   
  63.             printf("若元素%c有指向%c有边,则输入权值,否则输入无效值%d\t", pGraph->vertexArr[j], pGraph->vertexArr[i], INFINITY);  
  64.             scanf("%d",&( pGraph->arcArr[j][i]));  
  65.             printf("若元素%c有指向%c有边,则输入权值,否则输入无效值%d\t", pGraph->vertexArr[i], pGraph->vertexArr[j], INFINITY);  
  66.             scanf("%d",&( pGraph->arcArr[i][j]));  
  67.         }  
  68.     }  
  69.   
  70.   
  71. }  
  72.   
  73. void UArrayNet_show(UArrayNet *pGraph)  
  74. {  
  75.   
  76.   
  77.     printf("\n\n顶点元素如下\n");  
  78.     for (int i = 0; i < MAX_VERTEX; ++i)  
  79.     {  
  80.   
  81.         printf("%-5c", pGraph->vertexArr[i]);  
  82.     }  
  83.     printf("\n\n");  
  84.   
  85.   
  86.   
  87.     puts("边矩阵如下");  
  88.     printf("%-2c", ' ');  
  89.     for (int i = 0; i<MAX_VERTEX; ++i)  
  90.         printf("%-5c", pGraph->vertexArr[i]);  
  91.     putchar('\n');  
  92.   
  93.   
  94.   
  95.     for (int j = 0; j <MAX_VERTEX; ++j)  
  96.     {  
  97.         printf("%-2c", pGraph->vertexArr[j]);  
  98.         for (int i = 0; i < MAX_VERTEX; ++i)  
  99.         {  
  100.             if(pGraph->arcArr[i][j]==INFINITY)  
  101.             {  
  102.                 printf("%-5c", '#');  
  103.                   
  104.             }   
  105.             else  
  106.                 printf("%-5d", pGraph->arcArr[i][j]);  
  107.   
  108.         }  
  109.         putchar('\n');  
  110.     }  

 

  1. }  

 

 

 

 

 

 

 

 

 

 

http://blog.csdn.net/smarter_shability/article/details/69664755

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值