• 复杂数据结构(三 )图


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

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

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

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

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

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

    image

    图的存储可分为:

    邻接矩阵

    image

    邻接表

    image


    程序实现用邻接矩阵保存图:<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("输入各顶点信息
    ");
        for(i=0;i<G->VertexNum;i++) //输入顶点 
        {
            getchar();
            printf("第%d个顶点:",i+1);
            scanf("%c",&(G->Vertex[i])); //保存到各顶点数组元素中 
        }
        printf("输入构成各边的两个顶点及权值(用逗号分隔):
    "); 
        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("	%c",G->Vertex[j]);          //在第1行输出顶点信息 
        printf("
    ");
        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("");          //输出无穷大符号 
                else
                    printf("	%d",G->Edges[i][j]); //输出边的权值 
            }
            printf("
    ");
        }             
    }

    事件:

    #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("邻接矩阵数据如下:
    ");
        OutMatrix(&G);
        getch();
        return 0;
    }

    结果:

    image


    程序实现用邻接表保存图:<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("
    ");
        }
    }
    事件:
    #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("输入构成各边的两个顶点及权值(用逗号分隔):
    "); 
        CreateGraph(&G); //生成邻接表结构的图
        printf("输出图的邻接表:
    ");
        OutList(&G); 
        getch();
        return 0;
    }

    结果:

    image

  • 相关阅读:
    python入坑级
    nginx配置文件详解
    nginx看端口使用情况
    linux安装nginx
    linux安装jdk1.7
    linux设置tomcat开机启动
    redis master配置了密码进行主从同步
    linux搭建mysql 5.6.28
    linux搭建redis数据库
    找出一组数里出现频率最高的3个数(1.3)
  • 原文地址:https://www.cnblogs.com/moguwang/p/5283062.html
Copyright © 2020-2023  润新知