作者: 掖莯圷 | 来源:发表于2018-10-01 13:10 被阅读0次

    定义:

    图是由由顶点的有穷非空集合和顶点之间边的集合组成,可以定义为:
    G=(V, E)
    其中,
    V = {x|x∈某个数据元素集合}
    E ={(x,y)|x,y∈V} 或
    E = {<x, y>|x,y∈V并且Path(x, y)}

    其中,(x,y)表示从 x到 y的一条双向通路,即(x,y)是无方向的;Path(x,y)表示从 x到 y的一条单向通路,即Path(x,y)是有方向的。
    简单来说:G是图,V是图中顶点的集合,E是图中边的集合

    特点:

    在线性表中,每个元素之间只有一个直接前驱和一个直接后继,
    在树形结构中,数据结构是层次关系,并且每一层上的数据可能和下一层中多个元素相关,但只能和上一层中一个元素相关
    非线性结构,是研究数据元素之间的多对多的关系。在这种结构中,任意两个元素之间可能存在关系。即结点之间的关系可以是任意的,图中任意元素之间都可能相关

    基本术语

    \color{red}{顶点:}在图中的数据元素,我们称之为顶点(Vertex)
    \color{red}{边:}顶点之间的逻辑关系用边来表示,边集可以是空的
    \color{red}{无向边:}若顶点{V_i到V_j}之间的边没有方向,则称这条边为无向边,用无序偶({V_i,V_j})来表示
    \color{red}{无向图:}图中的每一条边都是没有方向的
    \color{red}{有向边:}若顶点{V_i到V_j}之间的边有方向,则称这条边为有向边,也称为弧(Arc),用有序偶<{V_i,V_j}>来表示,{V_i}称为弧尾,{V_j}称为弧头
    \color{red}{有向图:}图中的每一条边都是有方向的
    \color{red}{简单图:}在图结构中,若不存在顶点到其自身的边,且同一条边不重复出现,则称这样的图为简单图
    \color{red}{无向完全图:}在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。含有n个顶点的无向完全图有n(n-1)/2条边。
    \color{red}{有向完全图:}在有向图中,如果任意两个顶点之间都存在互为相反的两条弧,则称该图为有向完全图。含有n个顶点的无向完全图有n
    (n-1)条边。
    \color{red}{稀疏图和稠密图:}通常认为边或弧数小鱼n*logn(n是顶点的个数)的图称为稀疏图,反之称为稠密图。
    \color{red}{权:}有些边或弧带有与他相关的数字,这种与图的边或弧相关的数字,称为权
    \color{red}{网:}带权的图称为网
    \color{red}{子图:}假设有两个图,G1=(V1, E1) 和 G2=(V2, E2)。如果V2∈V1 且 E2∈E1,则称G2为G1的子图

    邻接矩阵

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #define isLetter(a)  ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
    #define LENGTH(a)  (sizeof(a)/sizeof(a[0]))
    typedef char vertexType;
    typedef int edgeType;
    typedef struct _GraphMatrix{
        int vertexNumber;// 顶点数
        int edgeNumber; // 边数
        vertexType *vertex;// 顶点集合
        edgeType **edge;// 邻接矩阵
    }GraphMatrix;
    
    void Printf_G(GraphMatrix *g){
        for(int i=0;i<g->vertexNumber;i++){
            for(int j=0;j<g->vertexNumber;j++){
                printf("%d\t",g->edge[i][j]);
            }
            printf("\n");
        }
    }
    void Printf_All(GraphMatrix *g){
        int flag=1;
        for(int i=0;i<g->vertexNumber;i++){
            if(flag){
                printf(" \t");
                flag=0;
            }
            printf("%c\t",g->vertex[i]);
        }
        printf("\n");
        for(int i=0;i<g->vertexNumber;i++){
            printf("%c\t",g->vertex[i]);
            for(int j=0;j<g->vertexNumber;j++){
                printf("%d\t",g->edge[i][j]);
            }
            printf("\n");
        }
    }
    /*
     * 返回ch在matrix矩阵中的位置
     */
    int Get_Position(GraphMatrix g, char ch){
        int i;
        for(i=0; i<g.vertexNumber; i++){
            if(g.vertex[i]==ch)
                return i;
        }
        return -1;
    }
    /*
     * 读取一个输入字符
     */
    char Read_Char(){
        char ch;
        do {
            ch = getchar();
        } while(!isLetter(ch));
        return ch;
    }
    void Init_GraphMatrix(GraphMatrix *g){
          //初始化图
        int v,e;
        printf("请输入顶点数量:");
        scanf("%d",&v);
        printf("请输入边数量:");
        scanf("%d",&e);
        if ( v < 1 || e < 1 || (e > (v * (v-1)))){
            printf("输入参数有误!\n");
            exit(0);
        }
        g->vertexNumber=v;
        g->edgeNumber=e;
        //分配空间
        g->vertex=(vertexType*)malloc(g->vertexNumber*sizeof(vertexType));
        // 初始化"边"
        g->edge=(edgeType**)malloc(g->vertexNumber*sizeof(edgeType));
        for(int i=0;i<g->vertexNumber;i++){
            g->edge[i]=(edgeType*)malloc(g->vertexNumber*sizeof(edgeType));
            for(int j=0;j<g->vertexNumber;j++){
                g->edge[i][j]=0;
            }
        }
        printf("初始化完毕\n");
        Printf_G(g);
    }
    
    
    GraphMatrix* Create_GraphMatrix(){
        char c1, c2;
        int p1, p2;
        GraphMatrix *g;
        if ((g=(GraphMatrix*)malloc(sizeof(GraphMatrix))) == NULL )
        return NULL;
        memset(g, 0, sizeof(GraphMatrix));
        Init_GraphMatrix(g);
        for (int i = 0; i < g->vertexNumber; i++){
            printf("请输入顶点(%d)的值: ", i);
            g->vertex[i] = Read_Char();
        }
        for (int i = 0; i < g->edgeNumber; i++){
            // 读取边的起始顶点和结束顶点
            printf("请输入边(%d)起始顶点和结束顶点:", i);
            c1 = Read_Char();
            c2 = Read_Char();
            p1=Get_Position(*g, c1);
            p2=Get_Position(*g, c2 );
            if (p1==-1 || p2==-1){
                printf("输入有误: 无效的边!\n");
                free(g);
                exit(0);
            }
            g->edge[p1][p2]=1;
            g->edge[p2][p1]=1;
        }
        Printf_All(g);
        return g;
    }
    
    
    int main()
    {
        GraphMatrix *gm=Create_GraphMatrix();
    
        return 0;
    }
    

    邻接表

    #include <stdio.h>
    #include <stdlib.h>
    typedef char vertexType;
    typedef struct ListEdgeNode{
        int index;                  // 边的下标
        struct ListEdgeNode *next;          // 指向下一个节点的指针
    }ListEdgeNode;
    
    typedef struct ListVertexNode {
        vertexType vertex;          // 顶点
         ListEdgeNode *fistEdge;        // 指向第一条边
    } ListVertexNode;
    
    typedef struct GraphList{
        int vertexNumber;           // 顶点的数量
        int edgeNumber;             // 边的数量
        ListVertexNode *vertex;     // 顶点集合,动态数组
    }GraphList;
    void GraphList_create(GraphList *g){
        printf("请分别输入图的顶点数量和边的数量,用空格隔开:");
        scanf("%d %d", &g->vertexNumber, &g->edgeNumber);       //将顶点数量和边的数量存储在结构体g中相应的变量
        //为动态数组申请空间
        g->vertex = (ListVertexNode*)malloc(g->vertexNumber * sizeof(ListVertexNode));
        //初始化顶点指的第一条边
        for (int i = 0; i < g->edgeNumber; i++){
            g->vertex[i].fistEdge = NULL;
        }
    
        //输入图的信息
        ListEdgeNode *listEdgeNode;
        for (int k = 0; k < g->edgeNumber; k++){
            int i, j;
            printf("请输入边(vi,vj)的下标, i和j,用空格隔开:");
            scanf("%d%d", &i, &j);
            //始终将插入的节点放在顶点所指的地一条边
            listEdgeNode = (ListEdgeNode *)malloc(sizeof(ListEdgeNode));
            listEdgeNode->index = j;
            listEdgeNode->next = g->vertex[i].fistEdge;
            g->vertex[i].fistEdge = listEdgeNode;
    
            listEdgeNode = (ListEdgeNode*)malloc(sizeof(ListEdgeNode));
            listEdgeNode->index = i;
            listEdgeNode->next = g->vertex[j].fistEdge;
            g->vertex[j].fistEdge = listEdgeNode;
    
        }
    
        //输出图的信息
        ListEdgeNode * len = NULL;
        for (int i = 0; i < g->vertexNumber; i++){
            
            if (g->vertex[i].fistEdge != NULL)
                len = g->vertex[i].fistEdge;
            while (len!= NULL){
                printf("%d --- %d\t", i,len->index);
                len = len->next;
            }
            printf("\n");
        }
    

    相关文章

      网友评论

          本文标题:

          本文链接:https://www.haomeiwen.com/subject/royxoftx.html