• 数据结构-邻接矩阵


    介绍

    邻接矩阵,是表示图的一种常见方式,具体表现为一个记录了各顶点连接情况的呈正方形的矩阵。

    假设一共有以下顶点,其连接关系如图所示

    那么,怎么表示它们之间的连接关系呢?

    我们发现,各条边所连接的都是两个顶点,联想到我们之前学过的能表示两个量直接关系的数据结构,二维数组就是一个不错的选择。

    如果i,j两个节点之间存在边联系它们,那么就将graph[i][j]值记为1,如果不存在边联系它们,就记为0.

    这样一来,可以表示图中节点关系的邻接矩阵可以具象化为:

    由于例图为无向图(即各顶点间路径没有具体指向),所以graph[i][j]与graph[j][i]的值相同,有向图中则需要将两个值单独判断

    具体实现

    根据输入的各条边的信息(即两个顶点)可以生成邻接矩阵

    1. cin>>n>>m;
    2. for (int i=0;i<n;i++) {
    3. for (int j=0;j<n;j++) {
    4. graph[i][j]=0;//初始化邻接矩阵
    5. }
    6. }
    7. for (int i=0;i<m;i++) {
    8. int u,v;
    9. cin>>u>>v;//读入边信息,更新邻接矩阵
    10. graph[u][v]=1;
    11. graph[v][u]=1; //如果是无向图,则还要更新graph[v][u]
    12. }
    13. for (int i=0;i<n;i++) {// 输出邻接矩阵
    14. for (int j=0;j<n;j++) {
    15. cout<<graph[i][j]<< " ";
    16. }
    17. cout<<endl;
    18. }

    根据邻接矩阵来实现各顶点相邻顶点的输出

    1)借助结构体来方便记录各顶点的相邻情况

    1. #define MAXN 100 // 最大顶点数
    2. int graph[MAXN][MAXN]; // 邻接矩阵
    3. struct Node{
    4. int value;
    5. int num;//记录相邻顶点数目
    6. Node** neib;//记录相邻顶点
    7. };

    2)遍历邻接矩阵,将相邻的顶点添入结构体内,记录相邻顶点

    1. Node* init(int v) {//初始化顶点信息
    2. Node* temp=(Node*)malloc(sizeof(Node));
    3. temp->value=v;
    4. temp->num=0;//邻居数开始为0
    5. temp->neib=NULL;//记录邻居的指针一开始为空
    6. return temp;
    7. }
    8. Node** generateGraph() {
    9. Node** nodes=(Node**)malloc(n*sizeof(Node*));//为结构体分配空间储存每个顶点信息
    10. for (int i=0; i<=n; i++) {
    11. nodes[i]=init(i);//初始化每一个顶点代表的结构体
    12. }
    13. for (int i=0; i<=n; i++) {
    14. for (int j=i; j<=n; j++) {
    15. if (graph[i][j]==1) {//如果两个顶点相邻
    16. addNeighbor(nodes[i],nodes[j]);
    17. addNeighbor(nodes[j],nodes[i]); // 无向图需要更新nodes[j]->neib
    18. m++;
    19. }
    20. }
    21. }
    22. return nodes;
    23. }

    3)为邻接矩阵中为1的两个顶点更新邻居信息

    1. void addNeighbor(Node* temp,Node* neighbor) {
    2. temp->num++;//邻居数增加
    3. //重新分配指针内存,增加指针数,用来指向新的邻居
    4. temp->neib=(Node**) realloc(temp->neib,temp->num*sizeof(Node*));
    5. temp->neib[temp->num-1]=neighbor;//记录新邻居地址
    6. }

    这里用realloc来重新分配内存空间

    malloc与realloc的不同:

    malloc:用于申请一块指定大小的内存空间,并返回指向该空间的地址

    realloc:接受两个参数:旧的内存指针与新的大小,用于重新调整一个已经分配完空间的内存大小,并可以将原空间的内容复制到新开辟的空间中,同时释放原内存

    4)输出顶点信息

    1. for (int i=0;i<=n;i++) {
    2. cout<<nodes[i]->value)<<":";
    3. for (int j=0;j<=nodes[i]->num;j++) {//输出所有相邻顶点
    4. cout<<nodes[i]->neib[j]->value<<" ";
    5. }
    6. cout<<endl;
    7. }

  • 相关阅读:
    buuctf crypto 【RSA】解题记录
    天线设计该如何入门
    DQL简介
    Git面试题整理(实操)
    Kibana8.4在Linux系统上的安装(ELK安装part3)
    先进制造aps专题九 中国aps行业分析
    QT之QLineEdit简介
    kubesz(一键安装k8s)
    Springboot老来福平台682f5计算机毕业设计-课程设计-期末作业-毕设程序代做
    PHP:匿名函数
  • 原文地址:https://blog.csdn.net/2302_80362563/article/details/136133835