zoukankan      html  css  js  c++  java
  • 数据结构中的图(图的存储结构)(2016-12-30)

    是由两个集合V和E组成的,V是有限的非空顶点集,E是V上的定点对所构成的边集,分别用V(g)和E(g)来表示图中的顶点集和边集,用二元组G=(V(g),E(g))来表示图G。

    图分为有向图无向图。

    有向图:<Vi,Vj>:表示从Vi开始到Vj的一条边。Vi为初始顶点或尾。Vj头或者终端顶点。有向边称为

    无向图:(Vi,Vj):边是无序的,所以(Vi,Vj)和(Vj,Vi)表示同一条边。

    无向完全图,有向完全图n个点全部连结起来的的图,而有向图的俩点间有互相相反的俩条边。

    强连通图,连通图,连通分量:

    路径,路径长度,简单路径和简单回路:

    一个顶点的度(TDi)=入度(IDi)+出度(ODi);

    图的存储结构:常用的有邻接矩阵、邻接表、邻接多重表、十字链表等。

    邻接矩阵表示方法:

    可以分为有权图and 无权图:

    有权图:aij表示<Vi,Vj>或者(Vi,Vj)的权重。若<Vi,Vj>或(Vi,Vj)不是E(g)中的边,则aij的值为0或者∞,∞表示一个计算机允许、大于所有边上权重的数,对于不存在的边,aij取0或者∞可以根据实际运算的需要或者方便而定。

    无权图:

    aij的取值如下,若顶点Vi和Vj之间没有边,则取值为0,若有边则取值为1。

    建立无向图邻接矩阵的算法如下:(顶点的英语为:vertex

    #define  MAXSIZE 100

    typedef int datatype;

    typedef struct

    {

      datatype vexs[MAXSIZE];//顶点信息表

      int edges[MAXSIZE][MAXSIZE];//邻接矩阵

      int n,e;//顶点数和边数

    }graph;

    void Creat_graph(graph *ga)

    {

      int i,j,k,w;//w为每条边的权重,j,i,k都为局部变量

      printf("请输入图的顶点数和边数: ");

      scanf("%d %d",&(ga->n),&(ga->e));

      printf("请输入顶点信息(顶点编号),建立顶点信息表: ");

      for(i=0;i<ga->n;i++)//输入顶点信息

        scanf("%c",&(ga->vexs[i]));

      for(i=0;i<ga->n;i++)//邻接矩阵初始化

        for(j=0;j<ga->n;j++)

          ga->edges[i][j]=0;

      for(k=0;k<ga->e;k++)//读入边的顶点编号和权重,建立邻接矩阵

      {

        printf("请输入第%d条边的顶点序号i,j和权重w:",k+1);

        scanf("%d,%d",&i,&j,&w);

        ga->edges[i][j]=w;

        ga->edges[j][i]=w;

      }  

    }

    特点:

    (1)无向图的邻接矩阵一定是对称的,而有向图的邻接矩阵不一定对称。因此用邻接矩阵表示一个具有n个定点的有向图时需要n^2个存储单元来存储邻接矩阵,对于n个顶点的无向图则需要n(n+1)/2个单元存储邻接矩阵;

    (2)对于无向图,邻接矩阵的第i行(或者第i列)中非零元素的个数正好是第i个顶点的度TD(vi),对于有向图,邻接矩阵的第i行(或者第i列)非零元素的个数正好是第i个顶点的出度OD(vi)(或者入度ID(vi));

    (3)用邻接矩阵很容易确定图中任意俩个顶点之间有边,但是不容易确定这个图中有多少条边。所以提出了邻接表

    算法的执行时间为O(n+n^2+e),由于e<n^2;所以算法的时间复杂度为O(n^2);

    邻接表表示法:

     由表头节点表节点组成:

    表头节点(data,first)

    表节点:(vertexs,next);

    无向图中:有n个顶点,e条边,则邻接链表需要n个头节点,2e个表节点,对于边很少的图来说,用邻接链表比用邻接矩阵更节省空间。

    在无向图的邻接链表中,第i个链表中的表节点数就是定点vi的度数,对于有向图来说,第i个链表中的表节点数就是顶点vi的出度数。

    表节点类型定义如下:

    #define nmax 100

    typedef struct node *pointer;

    typedef int datatype;

    struct node//表节点类型

    {

     int vertex;

     struct node *next; 

    }nnode;

    typedef struct //表头节点类型

    {

      datatype data;

      pionter first;//边表头指针

    }headtype;

    typedef struct{//表头节点向量,即顶点表

      headtype adlist[nmax];

      int n,e;//顶点数及边数

    }lkgraph;

    如果图中有n个顶点,e条边,则邻接表需要n个表头节点,e个表节点(有向图中)或2e个表节点(无向图中),因此空间复杂度为O(n+e);

    当边数较少时候,链表存储方式空间利用率较好,当变数较多时,邻接矩阵表示方法较好,如果运算中对所有的邻接点进行处理,则邻接矩阵和邻接表的时间复杂度分别为O(n^2)和O(n+e);

    void creatgraph(lkgraph *ga)

    {

      int i,j,e,k;

      pointer p;

      printf("请输入顶点数: ");

      scanf("%d",&(ga->n));

      for(i=1;i<=ga->n;i++)//读入顶点信息,建立顶点表

      {

        scanf(" %c",&(ga->adlist[i].data));

        ga->adlist[i].first=NULL;

      }

      e=0;//图中边的个数

      scanf(“ %d,%d ”,&i,&j);//读入一个顶点对号i和号j

      while(i>0)//顶点号大于零时候就存入

      {

        e++;

        //头节点为i的vi的链表

        p=(pointer)malloc(size(struct node));//生成新的邻接点序号为j的表节点

        p->vertex=j;//p的vertex存储j节点

        p->next=ga->adlist[i].first;//p->next指向NULL;

        ga->adlist[i].first=p;//将新表节点插入顶点vi的边表的头部

        //头节点为j的vj的链表

        p=(pointer)malloc(size(structnode));//生成新的临街点序号为i的表节点

        p->vertex=i;

        p->next=ga->adlist[j].first;//

        ga->adlist[j].first=p;//将新表节点插入到顶点vj的边表的头部

        scanf(" %d,%d ",&i,&j);//读入一个顶点对号i和j 

      }

      ga->e=e;

    }

    对上述建无向图邻接表的方法略加修改,可以得到有向图邻接表的建立方法

    建立有向图的邻接表

    void  cr_graph(lkgraph *ga)

    {

      int i,j,e,k;

      pointer p;

      printf("请输入顶点数: ");

      scanf("%d",&(ga->n));

      for(i=1;i<(ga->n);i++)//读入顶点信息,以及建立顶点表

      {

        scanf(" %c",&(ga->adlist[i].data));

        ga->adlist[i].first=NULL;

      }

      e=0;

      scanf(" %d,%d ",&i,&j);

      while(i>0)

      {

        e++;

        p=new node;

        p->vertex=j;

        p->next=ga->adlist[i].first;

        ga->adlist[i].first=p;

        scanf(" %d,%d ",&i,&j);

      }

      ga->e=e;

    }

    建立无向图算法的时间复杂度为O(n+e).(n为顶点个数,e表示图中边的个数)

  • 相关阅读:
    spring中@Autowired与 @Resource区别
    linux系统镜像iso文件下载
    log4j.properties配置说明学习网址
    maven常用命令
    mysql优化
    mybatis与hibernate区别
    struts2与SpringMVC区别
    java同步锁实现方法
    java多线程的四种实现方式
    java单例模式几种实现方式
  • 原文地址:https://www.cnblogs.com/hai5111/p/6236639.html
Copyright © 2011-2022 走看看