图的五种存储结构_邻接矩阵和邻接链表的建立

1.邻接矩阵

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

无向带权图的创建(邻接矩阵)

typedef char VertexType
typedef int EdgeType;
#define MAXVEX 100;
#define INFINITY 65535;//表示无限大
typedef struct{
    VertexType vexs[MAXVEX];
    EdgeType arc[MAXVEX][MAXVEX];
    int numVertexes,numEdges;
}MGraph;
void CreatMGraph(MGraph *Graph){
    int i,j,k,w;
    cout<<"请输入顶点数和边数:"<<endl;
    cin>>Graph->numVertexes;
    cin>>Graph->numEdges;
    for(i=0;i<Graph->numVertexes;i++){
        cin>>Graph->vexs[i];//建立点集合
    }
    for(i=0;i<Graph->numVertexes;i++){//边表初始化
        for ( j = 0; i < Graph->numVertexes; i++)
        {
            Graph->arc[i][j]=INFINITY;
        }   
    }
    for(k=0;k<Graph->numEdges;k++){
        cout>>"请输入边的首位字母下标和权值:"<<endl;
        cin>>i>>j>>w;
        Graph->arc[i][j]=w;
        Graph->arc[j][i]=w;//无向边的对称性
        
    }

}

2.邻接链表

在这里插入图片描述
在这里插入图片描述

无向图的建立(邻接表)

typedef char VertexType
typedef int EdgeType;
#define MAXVEX 100;

typedef struct EdgeNude{
    int adjvex;//边的指向下标
    EdgeType weight;
    struct EdgeNude *next;
}EdgeNude;

typedef struct VertexNude{
    VertexType data;
    EdgeNude *firstedge;

}VertexNude Adjlist[MAXVEX];

typedef struct{
    Adjlist adjlist;
    int numVertexes,numEdges;
}GraphAdjlist;
void CreatAdjlistGraph(GraphAdjlist *Graph){
    int i,j,k;
    EdgeNude *e;
    cout<<"输入顶点数和边数:"<<endl;
    cin>>Graph->numVertexes>>Graph->numEdges;
    for(i=0;i<Graph->numVertexes;i++){//顶点表建立和头指针初始化
        cout<<"输入顶点名:"<<endl;
        cin>>Graph->adjlist[i];
        Graph->adjlist[i].firstedge=NULL;
    }

    for(k=0;k<Graph->numEdges;K++){//头插法建立链表
        cout<<"请输入边字母两个下标:"<<endl;
        cin>>i>>j;
        e=(EdgeNude *)malloc(sizeof(EdgeNude));
        
        e->adjvex=j;
        e->next= Graph->adjlist[i].fistedge;
        Graph->adjlist[i].firstedge=e;
        //无向图的对称性
        e->adjvex=i;
        e->next= Graph->adjlist[j].fistedge;
        Graph->adjlist[j].firstedge=e;
    }

}

3.十字链表

对于有向图来说,邻接表是有缺陷的。关心了出度问题,想了解入度就必须要遍历整个图才能知道。反之,逆邻接表解决了入度

我们重新定义顶点表结点结构为:

data firstin firstout
其中firstin表示入边表头指针,指向该顶点的入边表中第一个结点,firstout表示出边表头指针,指向该顶点的出边表中的第一个结点。

重新定义的边表结点结构如下:

tailvex headvex headlink taillink
其中tailvex是指弧起点在顶点表的下标,headvex是指弧终点在顶点表中的下标,headlink是指入边表指针域,指向终点(弧头)相同的

下一条边,taillink是指出边表指针域,指向起点(弧尾)相同的下一条边。如果是网,还可以再增加一个weight域来存储权值。

如下图表示的十字链表:
在这里插入图片描述

4.邻接多重表

十字链表主要是针对有向图的存储结构进行了优化,那么对于无向图的邻接表,有没有问题呢?

如果我们在无向图的应用中,关注的重点是顶点,那么邻接表是不错的选择,但如果我们更关注边的操作,比如对已访问过的边做标记,删除某一条边等操作,那就意味着需要找到这条边的两个边表结点进行操作。如下图,若要删除(v0,v2)这条边,需要对邻接表结构中右边表的两个结点进行删除,显然这是比较繁琐的。
项目 | Value

  • ivex | ilink | jvex | jlink |

在这里插入图片描述
其中ivex和jvex是指某条边依附的两个顶点在顶点表中的下标。ilink指向依附顶点ivex的下一条边,jlink指向依附顶点jvex的下一条边。

这就是邻接多重表结构。如上图有4个顶点和5条边,先将边表结点画出来。由于是无向图,所以ivex,jvex正反过来都可以,为了绘图方便,都将ivex值设置的与一旁的顶点下标相同。

下面开始连线,首先连线的(1)(2)(3)(4)是将顶点的firstedge指向一条边,顶点下标要与ivex的值相同。接着,由于顶点v0的(v0,v1)边的

邻边有(v0,v3)和(v0,v2)。因此(5)(6)的连线就是满足指向下一条依附于顶点v0的边的目标,注意ilink指向的结点的jvex(ivex)一定要与它本身

的ivex的值相同。同理,连线(7)就是指(v1,v0)这条边,它是相当于顶点v1指向(v1,v2)边后的下一条。v2有三条边依附,所以(3)之后就有

了(8)(9)。连线(10)就是顶点v3在连线(4)之后的下一条边。左图一共有5条边,所以右图有10条连线,完全符合预期。

在这里插入图片描述

5.边集数组

边集数组是由两个一维数组构成。
一个是存储顶点的信息;另一个是存储边的信息,这个边数组每个数据元素由一条边的起点下标(begin)、终点下标(end)和权(weight)组成。
在这里插入图片描述
边集数组关注的是边的集合,在边集数组中要查找一个顶点的度需要扫描整个边数组,效率并不高。因此它更适合对边依次进行处理的操作,而不适合对顶点相关的操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值