数据结构与算法图的介绍和表示方法1

今天给大家介绍一种比较复杂的数据类型,也是最近我一直研究的数据类型,它就是图。

图的应用非常广泛,物理学、生物学、社会学和信息科学中可以使用图结构来建立研究模型,用来刻画客观的世界。比如在计算机科学中,图可以用来表示网络的通讯:网站的链接结构可以用有向图来表示,顶点代表网页,边代表链接关系。在社会学中,kevinbacon的“六度分隔理论”或者谣言传播理论的研究都可以使用图结构来建立模型。在我们常用的电子地图中,最常用的导航就是利用的图的结构,来规划路径、搜索道路等。

闲话少叙,让我们进入正题吧!

图是一种多对多的抽象数据类型,它由有限个顶点和有限条边组成。

顶点:是图的数据点,如u、v,w,y点等。

边:是数据点的关系,如(u,v)、(v,u)等。

有向图

在有向图中(u,v)和(v,u)是两个不同的边,这里我们称为弧,并且要使用尖括号。比如u,v是表示顶点u指向顶点v的弧,v,u是表示顶点v指向顶点u的弧。并且第一个顶点我们称为弧尾,第二个顶点称为弧头,弧的关系是由弧尾指向弧头。

无向图

在无向图中,(u,v)和(v,u)是相同的边,表示u和v之间连通。注意是”连通“,不是移动手机的那个联通。

图的一般表示方法有邻接矩阵、邻接链表。(另外还有一些表示方法,这里介绍最简单,最常用的表示方法。)

邻接矩阵:

邻接矩阵表示

邻接矩阵是一个二维V*V的矩阵(V是顶点个数),矩阵中一点M[u][v]的值,表示顶点u和顶点v的关系,等于1说明u和v有边,则u和v是连通的;等于0说明u和v没有边连接,则u和v不连通。另外M[u][v]的值可以用来表示权重,表示从顶点u到达顶点v所需要花费的代价。例如u和v表示两个城市,矩阵M表示城市里程图,若M[u][v]=d,则表示城市u和城市v的距离是d。

优点:邻接矩阵表示图的方法,简单、易于理解。查询、添加、删除、修改两顶点x和y的边,只需要O(1)复杂度。

缺点:需要耗费V*V个空间,即使多数点之间没有边,需要的空间还是V*V,很多的位置用来存放0。另外,若增加一个顶点x进入图中,则复杂度为O(V*V)。

邻接链表:

邻接链表

使用链表数组Array[V]来表示顶点的关系,数组的大小为V。每一个数组成员都是一个链表,表示该顶点在图中的连接情况。

Array[i]表示顶点i邻接边的连接关系,如上图,Array[0]表示顶点0与顶点1、顶点4都有边。Array[4]表示顶点4与顶点3、顶点0和顶点1都有边。

代码部分:

1.邻接矩阵

//C/C++代码演示邻接矩阵

#includeiostream

usingnamespacestd;

//顶点类

classNode

{

public:

  Node(chardata=0){

    m_cdata=data;

  }

  charm_cdata;

};

//图类

classmMap

{

public:

  mMap(intnumber){

    m_iNum=number;

    m_iIndex=0;

    m_pNodeArray=newNode[m_iNum];

    m_pMatrix=newint[m_iNum*m_iNum];

    for(inti=0;im_iNum*m_iNum;i++)m_pMatrix[i]=0;

  }

  ~mMap(){

    delete[]m_pMatrix;

    delete[]m_pNodeArray;

  };

//添加顶点

  booladdNode(Node*pNode){

    if(pNode==NULL)returnfalse;

    m_pNodeArray[m_iIndex].m_cdata=pNode-m_cdata;

    m_iIndex++;

    returntrue;

  }

//添加无向图的边

  booladdudtEdge(introw,intcol,intweight=1){

    if(row0

col0

rowm_iNum

colm_iNum)returnfalse;

    m_pMatrix[row*m_iNum+col]=weight;

    m_pMatrix[col*m_iNum+row]=weight;

    returntrue;

  }

//添加有向图的边

  booladddtEdge(introw,intcol,intweight=1){

    if(row0

col0

rowm_iNum

colm_iNum)returnfalse;

    m_pMatrix[row*m_iNum+col]=weight;

    returntrue;

  }

//打印图

  voidprint(){

    for(inti=0;im_iNum;i++){

      for(intj=0;jm_iNum;j++)

        coutm_pMatrix[i*m_iNum+j]"";

      coutendl;

    }

  }

private:

  intm_iNum;//顶点个数

  intm_iIndex;//顶点索引

  Node*m_pNodeArray;//顶点数组指针

  int*m_pMatrix;//邻接矩阵

};

intmain(){

  intnum=8;

  mMapmap(num);

  char*name="ABCDEFGH";

  for(inti=0;inum;i++){

    NodetempNode(name[i]);

    map.addNode(tempNode);

    chartemp=0;

  }

  coutendl;

  map.addudtEdge(0,1);

  map.addudtEdge(0,3);

  map.addudtEdge(1,2);

  map.addudtEdge(1,5);

  map.addudtEdge(3,6);

  map.addudtEdge(3,7);

  map.addudtEdge(6,7);

  map.addudtEdge(4,5);

map.print();

  return0;

}

输出结果:

2.邻接链表

//C/C++代码演示邻接链表

#includestdio.h

#includestdlib.h

//顶点结构体

structAdjListNode{

  intdest;

  structAdjListNode*next;

};

//顶点连接关系结构体

structAdjList

{

  structAdjListNode*head;//pointertoheadnodeoflist

};

//图

structGraph

{

  intv;//sizeofarraywillbeV(numberofverticesingraph)

  structAdjList*array;

  //AdjListpointerisaarrayofAdjLists

};

//创建一个顶点

structAdjListNode*newAdjListNode(intdest)

{

  structAdjListNode*newNode=(structAdjListNode*)malloc(sizeof(structAdjListNode));

  newNode-dest=dest;

  newNode-next=NULL;

  returnnewNode;

}

//创建有V个顶点的图

structGraph*createGraph(intv)

{

  structGraph*graph=(structGraph*)malloc(sizeof(structGraph));

  graph-v=v;

  //createaarrayofadjacencylist,sizeofarraywillbeV;

  graph-array=(structAdjList*)malloc(v*sizeof(structAdjList));

  //initializeeachadjlistasemptybymakingheadisNULL;

  inti;

  for(i=0;iv;i++){

    graph-array[i].head=NULL;

  }

  returngraph;

};

//向无向图中添加一条边

voidaddEdge(structGraph*graph,intsrc,intdest){

  //addanedgeformsrctodest

  //anewnodeisaddedtotheAdjListofsrc.

  structAdjListNode*newNode=newAdjListNode(dest);

  //wewillmakethenewNodepointtotheNodethatheadpointerpointedfirstly;

  newNode-next=graph-array[src].head;

  //andlettheheadpointtothenewNodesecondary

  graph-array[src].head=newNode;

  //UDTalsoneedanedgeformdesttosrc;

  newNode=newAdjListNode(src);

  newNode-next=graph-array[dest].head;

  graph-array[dest].head=newNode;

}

//打印图关系

voidprintGraph(structGraph*graph){

  intv;

  for(v=0;vgraph-v;++v){

    structAdjListNode*pCrawl=graph-array[v].head;

    printf("\nAdjListofvertex%d\nhead",v);

    while(pCrawl)

    {

      printf("-%d",pCrawl-dest);

      pCrawl=pCrawl-next;

    }

    printf("\n");

  }

}

intmain(){

  intv=5;

  structGraph*graph=createGraph(v);

  addEdge(graph,0,1);

  addEdge(graph,0,4);

  addEdge(graph,1,2);

  addEdge(graph,1,3);

  addEdge(graph,1,4);

  addEdge(graph,2,3);

  addEdge(graph,3,4);

  printGraph(graph);

  return0;

}

输出结果:

谢谢观看!欢迎在评论区交流学习!

扫一扫







































白癜风痒是不是快好啦
白癜风专科医院怎么走



转载请注明:http://www.92nongye.com/gaishu/204619080.html