图是一种复杂的非线性结构。

在线性结构中,数据元素之间满足唯一的线性关系,每个数据元素(除第一个和最后一个外)只有一个直接前趋和一个直接后继;

在树形结构中,数据元素之间有着明显的层次关系,并且每个数据元素只与上一层中的一个元素(双亲节点)及下一层的多个元素(孩子节点)相关;

而在图形结构中,节点之间的关系是任意的,图中任意两个数据元素之间都有可能相关。

图G由两个集合V(顶点Vertex)和E(边Edge)组成,定义为G=(V,E)

图可分为:无向图 and 有向图

复杂数据统计方法基于R与Python 复杂数据图_邻接表

 

图的存储可分为:

邻接矩阵

复杂数据统计方法基于R与Python 复杂数据图_复杂数据统计方法基于R与Python_02

邻接表

复杂数据统计方法基于R与Python 复杂数据图_邻接表_03


程序实现用邻接矩阵保存图:<AdjMatrixGraph>



#define VERTEX_MAX 26   //图的最大顶点数   
#define MAXVALUE 32767 //最大值(可设为一个最大整数) 
typedef struct
{
    char Vertex[VERTEX_MAX]; //保存顶点信息(序号或字母)
    int Edges[VERTEX_MAX][VERTEX_MAX]; //保存边的权 
    int isTrav[VERTEX_MAX]; //遍历标志 
    int VertexNum; //顶点数量 
    int EdgeNum;//边数量 
    int GraphType; //图的类型(0:无向图,1:有向图)    
}MatrixGraph; //定义邻接矩阵图结构 

void CreateMatrixGraph(MatrixGraph *G);//创建邻接矩阵图 
void OutMatrix(MatrixGraph *G); //输出邻接矩阵

void CreateMatrixGraph(MatrixGraph *G)//创建邻接矩阵图 
{
    int i,j,k,weight;
    char start,end; //边的起始顶点 
    printf("输入各顶点信息\n");
    for(i=0;i<G->VertexNum;i++) //输入顶点 
    {
        getchar();
        printf("第%d个顶点:",i+1);
        scanf("%c",&(G->Vertex[i])); //保存到各顶点数组元素中 
    }
    printf("输入构成各边的两个顶点及权值(用逗号分隔):\n"); 
    for(k=0;k<G->EdgeNum;k++)  //输入边的信息 
    {
        getchar(); //暂停输入 
        printf("第%d条边:",k+1);
        scanf("%c,%c,%d",&start,&end,&weight);
        for(i=0;start!=G->Vertex[i];i++); //在已有顶点中查找始点 
        for(j=0;end!=G->Vertex[j];j++); //在已有顶点中查找结终点 
        G->Edges[i][j]=weight; //对应位置保存权值,表示有一条边
        if(G->GraphType==0)  //若是无向图
            G->Edges[j][i]=weight;//在对角位置保存权值  
    }
}

void OutMatrix(MatrixGraph *G)//输出邻接矩阵 
{
    int i,j;
    for(j=0;j<G->VertexNum;j++)
        printf("\t%c",G->Vertex[j]);          //在第1行输出顶点信息 
    printf("\n");
    for(i=0;i<G->VertexNum;i++) 
    {
        printf("%c",G->Vertex[i]);
        for(j=0;j<G->VertexNum;j++)
        {
            if(G->Edges[i][j]==MAXVALUE) //若权值为最大值 
                printf("\t∞");          //输出无穷大符号 
            else
                printf("\t%d",G->Edges[i][j]); //输出边的权值 
        }
        printf("\n");
    }             
}



事件:



#include <stdio.h>
#include "AdjMatrixGraph.c"
int main()
{
    MatrixGraph G; //定义保存邻接矩阵结构的图 
    int i,j;
    printf("输入生成图的类型(0:无向图,1:有向图):");
    scanf("%d",&G.GraphType); //图的种类
    printf("输入图的顶点数量和边数量:");
    scanf("%d,%d",&G.VertexNum,&G.EdgeNum); //输入图顶点数和边数 
    for(i=0;i<G.VertexNum;i++)  //清空矩阵 
        for(j=0;j<G.VertexNum;j++)
            G.Edges[i][j]=MAXVALUE; //设置矩阵中各元素的值为最大值         
    CreateMatrixGraph(&G); //创建用邻接表保存的图 
    printf("邻接矩阵数据如下:\n");
    OutMatrix(&G);
    getch();
    return 0;
}



结果:

复杂数据统计方法基于R与Python 复杂数据图_复杂数据统计方法基于R与Python_04


程序实现用邻接表保存图:<AdjListGraph>



#define VERTEX_MAX 20   //图的最大顶点数   
typedef struct edgeNode   
{
    int Vertex; //顶点信息(序号或字母) 
    int weight; //权值
    struct edgeNode *next; //指向下一个顶点指针 (当前顶点和指向的下一顶点构成一条边) 
}EdgeNode; //邻接表边结构 

typedef struct   
{
    EdgeNode* AdjList[VERTEX_MAX]; //指向每个顶点的指针
    int VextexNum,EdgeNum; //图的顶点的数量和边的数量  
    int GraphType; //图的类型(0:无向图,1:有向图)
}ListGraph;  //图的结构 

void CreateGraph(ListGraph *G); //生成图的邻接表   
void OutList(ListGraph *G); //输出邻接表

void CreateGraph(ListGraph *G)  //构造邻接表结构图
{
    int i,weight;
    int start,end;
    EdgeNode *s;
    for(i=1;i<=G->VextexNum;i++)//将图中各顶点指针清空 
        G->AdjList[i]=NULL;
    for(i=1;i<=G->EdgeNum;i++) //输入各边的两个顶点 
    {
        getchar();
        printf("第%d条边:",i); 
        scanf("%d,%d,%d",&start,&end,&weight); //输入边的起点和终点
        s=(EdgeNode *)malloc(sizeof(EdgeNode)); //申请保存一个顶点的内存 
        s->next=G->AdjList[start]; //插入到邻接表中 
        s->Vertex=end; //保存终点编号
        s->weight=weight; //保存权值 
        G->AdjList[start]=s; //邻接表对应顶点指向该点 
        if(G->GraphType==0) //若是无向图,再插入到终点的边链中
        {
            s=(EdgeNode *)malloc(sizeof(EdgeNode)); //申请保存一个顶点的内存 
            s->next=G->AdjList[end];
            s->Vertex=start;
            s->weight=weight;
            G->AdjList[end]=s;
        }
    }   
} 
void OutList(ListGraph *G)
{
    int i;
    EdgeNode *s;
    for(i=1;i<=G->VextexNum;i++)
    {
        printf("顶点%d",i); 
        s=G->AdjList[i];
        while(s)
        {
            printf("->%d(%d)",s->Vertex,s->weight); 
            s=s->next;
        }
        printf("\n");
    }
}


事件:

#include <stdio.h>
#include "AdjListGraph.c"
int main()
{
    ListGraph G; //定义保存邻接表结构的图 
    printf("输入生成图的类型(0:无向图,1:有向图):");
    scanf("%d",&G.GraphType); //图的种类
    printf("输入图的顶点数量和边数量:");
    scanf("%d,%d",&G.VextexNum,&G.EdgeNum); //输入图顶点数和边数 
    printf("输入构成各边的两个顶点及权值(用逗号分隔):\n"); 
    CreateGraph(&G); //生成邻接表结构的图
    printf("输出图的邻接表:\n");
    OutList(&G); 
    getch();
    return 0;
}



结果:

复杂数据统计方法基于R与Python 复杂数据图_邻接表_05