第六章学习小结

一、图的存储结构

(1)邻接矩阵

若保存的图是无权值的图,有边则为1,无边则为0;

若保存的图是网(即带权值),有边的则为对应边上的权值,无边的则是取计算机允许的、大于所有边上权值的数(用INT-MAX表示)

代码如下所示:

#define MVNum 100

typedef char VerTexType;

typedef int ArcType;//由于不知道后续的顶点、权值具体是什么类型,后面均用VexTexType,ArcType表示,便于修改

typedef struct

{

  VerTexType vexs[MVNum];

  ArcType arcs[MVNum][MvNum];

  int vexnum,arcnum;

}AMGraph;

便于计算各个顶点的度,用于稀疏图时极其的浪费空间

(2)邻接表:由两部分组成:表头结点表、边表

表头结点表:以顺序结构的形式存储,包括数据与和链域两部分

边表:表示图中顶点间的关系,包括邻接点域、数据域和链域三部分

代码如下所示:

typedef struct ArcNode

{

  int adjvex;//该边所指向的顶点位置

  struct ArcNode *nextarc;//指向下一条边的指针

  OtherInfo info;

}ArcNode;//边表

typedef struct VNode

{

  VerTexType data;

  ArcNode *firstarc;//指向第一条依附该顶点的指针

}VNode,AdjList[MVNum];

typedef struct

{

  AdjList vertices;//相当于重新取了个名字叫vertices,等价于VNode vertices[MVNum];

  int vexnum,arcnum;

}ALGraph;

便于增加和删除结点,但是计算有向图顶点的度时很不方便,适用于稀疏图,且不便于判断顶点之间是否有边

计算有向图顶点的度:顶点的度=该顶点的入度+出度

出度=第i个链表中的结点的个数

入度=在所有链表中,其邻接点域的值为i的结点的个数或者利用逆邻接表用邻接表求出度的方式求入度

二、图的遍历

(1)深度优先遍历(DFS):类似于树的先序遍历,主要应用了递归

 bool visited[MVNum];//使用前记得初始化为false

//邻接矩阵表示法

void DFS_AM(AMGraph G,int v)

{

  cout << v;

  visited[v] = true;

  for(w=0;w<vexnum;w++)

  {

    if(G.arcs[v][w]!=0 && !visited[w]) DFS_AM(G,w);

  }  

}

邻接表表示法

void DFS_AL(ALGraph G,int v)

{

  cout <<v;

  visited[v] = true;

  p = G.vertices[v].firstarc;

  while(p != NULL)

  {

    w = p->adjvex;

    if( !visited[w]) DFS_AL(G,w);

    p = p->nextarc;

  }

}   

(2)广度优先遍历(BFS):类似于树的层次遍历,利用了队列

void BFS(Graph G,int v)

{

  cout << v;

  visited[v] = true;

  queue<int> Q;//自动初始化队列

  Q.push(v);

  while( !Q.empty() )

  {

    u = Q.front();//取对头元素

    Q.pop();//对头元素出队

    for(w = FirstAdjVex(G,u);w>=0;w = NextAdjVex(G,u,w))

    {

      if( !visited[w])

      {

        cout << w;

        visited[w] = true;

        Q.push(w);

      }

    }

  }

}

注:以上两种算法均针对连通图,若想遍历非连通图,只需在最外层套一个循环

如:for(int i=0;i<vexnum;i++)

  {

    if( ! visited[i]) DFS_AM(G,i);

  }

三、图的应用

(1)最小生成树:最小生成树不唯一,掌握普利姆算法(也称“加点法”)和克鲁斯卡尔算法(也称“加边法)

根据老师的直播以及慕课的视频,能够用手动运行的方式写出每一次运行的结果

(2)最短路径(迪杰斯特拉算法)

 四、pta作业和实践

实践(解救007)遇到的问题:

1、题意没摸清就开始写代码,做了很多的无用功

2、判断是否能跳到岸边时,漏了判断条件,忘了是坐标,可以为正或负

3、没有巧妙的运用0 1,所有的判断都用了true和false,写起来造成了一定的不方便;且一开始没有很好的掌握全局变量,以至于在写函数的时候,参数总是捉摸不定,而且有很多,还应用了引用

    

  

posted @ 2020-06-14 21:40  徐晴芳  阅读(254)  评论(0编辑  收藏  举报