图的存储结构:邻接矩阵与邻接表

2022-09-01  本文已影响0人  lxr_

图的存储结构

由于图结构比较复杂,无法用简单的顺序存储结构来表示。而多重链表的方式,即以一个数据域和多个指针域组成的结点表示图中的一个顶点,尽管可以实现图结构,但各个顶点的度数相差很大,按读数最大的顶点设计结点结构会造成很多浪费,而按照每个顶点自己的度数设计不同的顶点结构又带来操作不便,看以下存储结构。

邻接矩阵:

邻接矩阵优点:
直观、简单、好理解
方便检查任一对顶点间是否存在边
方便找任一顶点的所有“邻接点”
方便计算任一顶点的“度”

缺点:
不便于增加和删除顶点
浪费空间—存稀疏图(点很多而边很少)有大量无效元素,对稠密图比较合算。
浪费时间—统计稀疏图中一共有多少条边。

邻接矩阵创建代码
MGraph.h

#pragma once

typedef char VertexType;        //顶点类型
typedef int EdgeType;           //边类型
#define MAXVEX  100             //最大顶点数目
#define MAXEDGE 65536           //用65536代表无穷

typedef struct
{
    VertexType vexs[MAXVEX];    //顶点数组
    EdgeType arc[MAXVEX][MAXVEX];//边数组

    int numVertexes, numEdges;  //图中实际的顶点数和边数
}MGraph;

//创建无向网图
void CreateMGrah(MGraph& G);

//查询顶点索引
int LocateVex(MGraph G, VertexType v);

MGraph.cpp

#include "MGraph.h"
#include <iostream>

using namespace std;

//创建无向网图的邻接矩阵
void CreateMGrah(MGraph& G)
{
    cout << "请输入顶点个数和边个数:" << endl;
    cin >> G.numVertexes >> G.numEdges;

    cout << "请输入" << G.numVertexes << "个顶点:" << endl;
    for (int i = 0; i < G.numVertexes; i++)
    {
        cin >> G.vexs[i];                       //输入顶点
    }

    for (int i = 0; i < G.numVertexes; i++)
    {
        for (int j = 0; j < G.numVertexes; j++)
        {
            if (i == j)
            {
                G.arc[i][j] = 0;                
            }
            else
            {
                G.arc[i][j] = MAXEDGE;              //边初始化为无穷

            }
        }
    }

    cout << "请输入" << G.numEdges << "条边:" << endl;
    VertexType vertex1, vertex2;
    EdgeType edge;
    for (int i = 0; i < G.numEdges; i++)
    {
        cin >> vertex1 >> vertex2 >> edge;
        int m = LocateVex(G, vertex1);
        int n = LocateVex(G, vertex2);

        if (m >= 0 && n >= 0)
        {
            G.arc[m][n] = edge;
            G.arc[n][m] = edge;
        }
    }
}

//查询顶点索引
int LocateVex(MGraph G, VertexType v)
{
    for (int i = 0; i < G.numVertexes; i++)
    {
        if (v == G.vexs[i])
        {
            return i;
        }
    }
    return -1;
}

邻接表表示法

将数组与链表相结合的存储方法侧好难过为邻接表(Adjacency List)。

邻接矩阵与邻接表表示法的关系:

邻接表创建代码
ALGraph.h

#pragma once

#define MAXVEX 100
typedef char VertexType;        //顶点类型
typedef int EdgeType;           //边上的权值类型

struct EdgeNode                 //边表结点
{
    int adjvex;                 //邻接点域,存储该节点对应的下标

    EdgeType weight;            //存储权值,非网图不需要
    EdgeNode* next;             //下一个邻接点
};

typedef struct VertexNode
{
    VertexType data;            //顶点

    EdgeNode* firstEdge;        //边表头指针
}AdjList[MAXVEX];               //顶点数组

struct GraphAdjList
{
    AdjList adjList;            //顶点数组
    int numVertexes, numEdges;  //实际图中顶点数和边数
};

//建立无向图的邻接表结构
void CreateALGraph(GraphAdjList& G);

//根据顶点名称查找其下标
int locateVertex(GraphAdjList G, VertexType v);

ALGraph.cpp

#include "ALGraph.h"

#include <iostream>
using namespace std;

//建立无向图的邻接表结构
void CreateALGraph(GraphAdjList& G)
{
    cout << "请输入顶点个数和边个数:" << endl;
    cin >> G.numVertexes >> G.numEdges;

    cout << "请输入" << G.numVertexes << "个顶点:" << endl;
    for (int i = 0; i < G.numVertexes; i++)
    {
        cin >> G.adjList[i].data;
        G.adjList[i].firstEdge = NULL;
    }

    cout << "请输入" << G.numEdges << "条边:" << endl;

    VertexType vertex1, vertex2;
    int m, n;
    int edge;
    for (int i = 0; i < G.numEdges; i++)
    {
        cin >> vertex1 >> vertex2 >> edge;      //输入边及其依附的两个顶点

        m = locateVertex(G, vertex1);
        n = locateVertex(G, vertex2);

        if (m >= 0 && n >= 0)
        {
            //创建一个新的边结点
            EdgeNode* n1 = new EdgeNode;
            n1->weight = edge;
            n1->adjvex = n;
            n1->next = G.adjList[m].firstEdge;  //头插法插入顶点的firstedge
            G.adjList[m].firstEdge = n1;

            //由于是无向图,还需要插入到第n个顶点的边表中
            EdgeNode* n2 = new EdgeNode;
            n2->weight = edge;
            n2->adjvex = m;
            n2->next = G.adjList[n].firstEdge;
            G.adjList[n].firstEdge = n2;

        }
    }
}

//根据顶点名称查找其下标
int locateVertex(GraphAdjList G, VertexType v)
{
    for (int i = 0; i < G.numVertexes; i++)
    {
        if (v == G.adjList[i].data)
        {
            return i;
        }
    }
    return -1;
}

main.cpp

#include <iostream>
#include "MGraph.h"
#include "ALGraph.h"

using namespace std;

int main(int argc, char** argv)
{
    //1.邻接矩阵
    MGraph MG;
    CreateMGrah(MG);

    //2.邻接表
    GraphAdjList ALG;
    CreateALGraph(ALG);

    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读