图 (中)

图的存储

邻接矩阵

考虑到图是由顶点和边(弧)两部分组成,那就分成两部分存储。

图的邻接矩阵存储方式是用两个数组表示图,一个一维数组存储图中的顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或者弧的信息。

设图G中有n个顶点,则邻接矩阵是一个n×n 的方阵,定义为

arc[i][j]={1,0,若(vi,vj)∈E或<vi,vj>∈E反之

实际举例:

无向图:

顶点数组:

A B C D

边数组:

顶点ABCDA0101B1011C0101D1110

特点:

  1. 无向图的邻接矩阵是一个对称矩阵。主对角线(左上角–>右下角)上线的元素是相等的。
  2. 某个顶点的度等于第i行的元素之和.B的度是1+0+1+1=3 度为3
  3. 顶点i的所有邻接点就是第i行的元素中为1的点.

有向图:

顶点数组:

A B C D

边数组:

顶点ABCDA0000B1000C1000D0110

有向图的邻接矩阵一般不是对称的。

网图

每条边上带权的图叫做网

如何存储

arc[i][j]=???Wij,0,∞,若(vi,vj)∈E或<vi,vj>∈E若i==j反之

这里的wij表示权值,∞表示一个计算机允许的、大于所有边上权值的值,也就是一个不可能的值。一般表示不可达。

顶点数组:

A B C D

边数组:

顶点ABCDA0∞∞∞B60∞∞C9∞0∞D∞780

代码实现:

#include <stdio.h>

typedef char VertexType; /*顶点的数据类型*/

typedef int EdgeType; /*权值类型*/

#define MAXVEX 100 /*最大定点数*/

#define INFINITY 65535 /*不可达*/

typedef struct Graph
{
    VertexType vesx[MAXVEX]; // 定点表
    EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵
    int numVertexs; //当前的定点数
    int numEdges; //当前的边数
}Graph;

/**
 * @author 韦轩
 * @time 2015/08/30
 * @brief 邻接矩阵创建无向图
 * @param G
 * @return
 */
void createUdGraph(Graph* G)
{
    printf("Input the vertexts and the edges :\n");
    scanf_s("%d,%d", &G->numVertexs, &G->numEdges);

    int i, j, w;
    for (i = 0; i < G->numVertexs;i++)
    {
        scanf_s(&G->vesx[i]);
    }

    for (i = 0; i < G->numEdges; i++)
    {
        for (j = 0; j < G->numVertexs;j++)
        {
            G->arc[i][j] = INFINITY;//初始化
        }
    }

    for (int k = 0; k < G->numEdges;k++)
    {
        printf("Input the (Vi,Vj) and the weight :\n");
        scanf_s("%d,%d,%d", &i, &j, &w);
        G->arc[i][j] = w;
        G->arc[j][i] = G->arc[i][j];
    }
}

可以看出,N个顶点和E条边的无向图的创建,时间复杂度是

O(N+N2+E),其中邻接矩阵的初始化,需要O(N2)

邻接表

当边数比较少的时候,邻接矩阵对空间的浪费比较严重.

为了避免空间浪费的问题,引入了邻接表的方式:数组与链表相结合的存储方法称为邻接表(Adjacency List)

处理办法:

顶点表:图中的顶点使用一个一维数组存储,为每一个还需要存储一个指向第一个邻接点的指针。

图中的每个顶点Vi的所有邻接点构成一个线性表,使用单链表存储。

无向图:

邻接表

顶点表的的各个结点由data域和firstedge两个域组成,data是数据域,存储节点信息,firstedge是指针域,指向边表的第一个结点,即此节点的第一个邻接点。

边表结点有adjvex和next指针域组成,adjvex是邻接点域,存储某顶点的邻接点在定点表中的下标。next则指向边表中下一个结点的指针。

有向图:

带权:

在边表结点增加weight数据域

代码实现

#include <stdio.h>
#include <malloc.h>
typedef char VertexType;

typedef int EdgeType; //权值类型

#define MAXVEX 100

/**
 * @author 韦轩
 * @time 2015/08/30
 * @brief 边表结点
 *
 */
typedef struct EdgeNode
{
    int adhvex; //邻接点域,存储该顶点对应的下标
    EdgeType weight;//权值
    struct EdgeNode* next;//指针域,指向下一个邻接点
}EdgeNode;

/**
 * @author 韦轩
 * @time 2015/08/30
 * @brief 顶点表结点
 */
typedef struct VertexNode
{
    VertexType data; //顶点域,存储顶点信息
    EdgeNode* firstedge; //边表头指针
}VertexNode, AdjList[MAXVEX];

/**
 * @author 韦轩
 * @time 2015/08/30
 * @brief 图
 */
typedef struct GraphAdjList
{
    AdjList adjList;
    int numVertexs; //当前的顶点数
    int numEdges; //当前的边数
}GraphAdjList;

void creatGraph(GraphAdjList* G)
{
    int i, j, k;
    EdgeNode* edgeNode;
    printf("Input the vertexs and edges:\n");
    scanf_s("%d,%d", &G->numVertexs, &G->numEdges);
    /*
        读入顶点信息,建立顶点表
    */
    for (i = 0; i < G->numVertexs;i++)
    {
        scanf_s(&G->adjList[i].data);
        G->adjList[i].firstedge = NULL;//边表置为空表
    }

    for (k = 0; k < G->numEdges;k++)
    {
        printf("Input the vi vj:\n");
        scanf_s("%d,%d", &i, &j);

        edgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));//分配内存

        /*
            生成边表结点
        */
        edgeNode->adhvex = j;//邻接序号为j

        /*
            将edgeNode指针指向当前顶点指向的结点
        */
        edgeNode->next = G->adjList[i].firstedge;

        /*
            将当前顶点的指针指向edgeNode
        */
        G->adjList[i].firstedge = edgeNode;

        edgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));//分配内存

        edgeNode->adhvex = i;

        edgeNode->next = G->adjList[j].firstedge;

        /*
        将当前顶点的指针指向edgeNode
        */
        G->adjList[j].firstedge = edgeNode;
    }
}

可以看出,N个顶点和E条边的无向图的创建,时间复杂度是

O(N+E)

十字链表

邻接多重表

边集数组

版权声明:欢迎交流

时间: 2024-10-26 17:16:58

图 (中)的相关文章

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

在图中寻找最短路径-----深度优先算法C++实现

求从图中的任意一点(起点)到另一点(终点)的最短路径,最短距离: 图中有数字的点表示为图中的不同海拔的高地,不能通过:没有数字的点表示海拔为0,为平地可以通过: 这个是典型的求图中两点的最短路径:本例,用深度优先算法来实现: 在每一个点都有四个方向(有的点的有些方向不能通过),所以在每一个点处要处理四种方向的情况: 深度优先算法函数怎么写? 也就是写递归函数...但是递归函数肿么写??? 第一:判断初始态,从起点出发,刚开始步数为0:dfs(start_x, start_y, 0); 第二:从起

解决zabbix图中出现中文乱码问题

我这周部署了zabbix监控服务器,但是配置过程中发现当有中文时,图中的中文会变成方块 如下图所示: 这个问题是由于zabbix的web端没有中文字库,我们最需要把中文字库加上即可 解决办法如下: 1.从windows下控制面板->字体->选择一种中文字库例如"楷体" 2.把它拷贝到zabbix的web端的fonts目录下例如:/data/www/zabbix/fonts/,并且把TTF后缀改为ttf 3.修改zabbix的web端/include/defines.inc.

python—networkx:在一张图中画出多个子图

通过plt.subplot能够在一张图中画出多个子图 #coding: utf-8 #!/usr/bin/env python """ Draw a graph with matplotlib. You must have matplotlib for this to work. """ __author__ = """Aric Hagberg ([email protected])"""

图中最短路径算法(Dijkstra算法)(转)

1.Dijkstra 1)      适用条件&范围: a)   单源最短路径(从源点s到其它所有顶点v); b)   有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图) c)   所有边权非负(任取(i,j)∈E都有Wij≥0); 2)      算法描述: 在带权图中最常遇到的问题就是,寻找两点间的最短路径问题. 解决最短路径问题最著名的算法是Djikstra算法.这个算法的实现基于图的邻接矩阵表示法,它不仅能够找到任意两点的最短路径,还可以找到某个指定点到其他

矩阵图中的广度优先搜索

经常会有类似的题目,如迷宫问题,在一个矩阵图中给定出发点和目标点,每次只能上下左右移动,求到目标点的最短走法,或者说是一共有多少种走法. 思路其实很简单,深搜.广搜.相对比较而言,广度优先搜索更加实用于求最短的走法(步数) 在矩阵图中的广搜需要注意一下几点. 1.确定每步的走法:不同题的走法可能不同,每次搜索时将走法保存在数组中. 2.确定初始状态 往往注意刚开始得起点(i,j)必须把MAP(i,j)改变为 -1(或者其他的),栈中第一个元素即为初始状态 3.保存状态.这点很重要.需要用数组或者

javascript实现有向无环图中任意两点最短路径的dijistra算法

有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijk

类图及类图中的关系

1.类图和对象图  类图(Class Diagram)是显示出类.接口以及他们之间的静态结构与关系的图.其中最基本的单元是类或接口. 类图不但可以表示类(或者接口)之间的关系,也可以表示对象之间的关系.下面是一个典型的类图: 类图一般分为几个部分:类名.属性.方法.下面分别讲解. (1)类名 上面的Car就是类名,如果类名是正体字,则说明该类是一个具体的类,如果类名是斜体字,则说明类是一个抽象类abstract. (2)属性列表 属性可以是public.protected.private.pub

十字链表的方式实现在头部插入图中节点

#include<stdio.h> #include<malloc.h> #define MAX_VERTEX_NUM 20 typedef struct ArcBox{ int tailvex,headvex;//该弧的头和尾定点的位置 struct ArcBox *hlink,*tlink;//分别为弧头和弧尾相同的弧的链域 int *info; }ArcBox; typedef struct VexNode //顶点结点 { char data; //顶点信息(标识) Arc

使用axes函数在matlab绘图中实现图中图的绘制

使用axes函数在matlab绘图中实现图中图的绘制 有时为了对细节进行详细说明,需要在一个较大坐标轴上绘制一个小图来对局部进行放大以阐述结果. 这可以通过调用axes函数实现. 下面通过绘制 y=1/(t-3) 的曲线举例说明该函数的使用方法. 程序如下: clc;clear;close all;