数据结构第七周笔记——图(中3)(慕课浙大版本--XiaoYu)

简介: 小白专场,实现案例:哈利波特的考试,并进行逐句讲解

小白专场:哈利 波特的考试-C语言实现

小白-HP.1 题意理解

网络异常,图片无法展示
|

样例第一列表示动物的个数(也就是顶点的个数)      第二列表示边的个数

D是最短距离的矩阵,记录从顶点i到顶点j之间的最短距离

Harry究竟应该带哪只动物去的问题的时候,首先检查每一行里面最大的那个数字,最大的那个数字代表着第一个动物变成最大数字的那个动物是最麻烦的,无穷符号指当前的那个动物

要带什么动物去会使我们最难变的动物变成最好变的呢?答案是动物4号,它最难变的咒语是70

小白-HP.2 程序框架搭建

intmain()

{

   读入图;

   分析图;

   return0;

}

代码实际演示

intmain()

{

   //有两种图,一种邻接表的,一种邻接矩阵的。这里选择了邻接矩阵的方法来表示图

   GraphG=BuildGraph();

   FindAnimal( G );

   return0;

}

//FindMaxDist(i)是最大距离,对第i个动物去求他所有最短距离里面的最大值,要求的是所有这些最大值里面的最小值

//FindMin是最小距离

网络异常,图片无法展示
|

小白-HP.3 选择动物

voidFindAnimal(MGraphGraph)

{

   WeightTypeD[MaxVertexNum][MaxVertexNum],MaxDist,MinDist;

   VertexAnimal, i;

   

   Floyd(Graph , D);

   

   //FindMin:从每个动物i的最短距离的最大值中,找到最小值MinDist,以及对应的动物编号Animal

   MinDist=INFINITY;

   for( i=0;i<Graph->Mv;i++){

       MaxDist=FindMaxDist(D,i,Graph->Nv);//找到第i个动物它的最大的那个距离赋给MaxDist这个变量

   

   //还有一个特殊情况需要考虑:带一只动物去根本不可能,当图不连通的时候,图有不止一个连通集。该从哪里意识到图不连通了呢?

       if(MaxDist==INFINITY){//返回距离无穷大的话说明有i无法变出的动物

           printf("0\n");

           return;

       }

       

       

       if( MinDist>MaxDist ){//找到最长距离更小的动物

           MinDist=MaxDist; Animal=i+1;//更新距离,记录编号。这里是i+1是因为动物编号从1开始,但是图的循环从0开始,所有需要加一

       }

   }      

   printf("%d %d\n",Animal,MinDist);

}

上述代码中涉及到封装起来的函数

WeightTypeFindMaxDist(WeightTypeD[][MaxVertexNum],Vertexi,intN)

{

   WeightTypeMaxDist;

   Vertexj;

   

   MaxDist=O;//初始化为一个很小的数,比如0

   for(j=0;j<N;j++ )//找出i到其他动物j的最长距离

       if( i!=j&&D[i][j]>MaxDist )//邻接矩阵所有的两个顶点之间的距离全部初始化为正无穷,所以对角元的值永远是正无穷。所以必须要把对角元排除掉跳过去,不排除的话这个无穷大必然会符合这个判断条件从而让MaxDist永远的返回正无穷

           MaxDist=[i][j];

   returnMaxDist;

}

小白-HP.4 模块的引用与裁剪

网络异常,图片无法展示
|

#define MaxVertexNum 100//最大顶点数设置为100

#define INFINITY 65535//无穷大设为双字节无符号整数的最大值65535

typedefintVertex//用顶点下标表示顶点,为整型

typedefintWeightType;//边的权值设为整型

//边的定义

typedefstructENode*PtrToENode;

structENode{

   VertexV1,V2;//有向边<V1,V2>

   WeightTypeWeight;//权重

};

typedefPtrToENodeEdge;

//图结点的定义

typedefstructGNode*PtrToENode;

structGNode{

   intNv;//顶点数

   intNe;//边数

   WeightTypeG[MaxVertexNum][MaxVertexNum];//邻接矩阵

   DataTypeData[MaxVertexNum];//存顶点的数据

   //注意:很多情况下,顶点无数据,此时Data[]可以不出现

};

typedefPtrToENodeMGraph;//以邻接矩阵存储的图类型

CreateGraph原始代码

MGraphCreateGraph(intVertexNum)

{/*初始化一个有VertexNum个顶点但没有边的图*/

   VertexV,W;

   MGraphGraph;

   

   Graph=(MGraph)malloc(sizeof(structGNode));/*建立图*/

   Graph->NvVertexNum;

   Graph->Ne=0;

/*初始化邻接矩阵*/

/*注意:这里默认顶点编号从0开始,到(Graph->Nv-1)*/

for (V=0; V<Graph->Nv; V++)

   for (W=0; W<Graph->Nv; W++)

       Graph->G[V][W] =INFINITY;

   returnGraph;

}

voidInsertEdge(MGraphGraph,EdgeE)

{

/*插入边<V1,V2>*/

   Graph->G[E->V1][E->V2] =E->Weight;

/*若是无向图,还要插入边<V2,V1>   因为是无向图,所以我们需要把读进来的这个权重同时赋予矩阵里面两个元素*/

   Graph->G[E->V2][E->V1] =E->Weight;

MGraphBuildGraph()

{

   MGraphGraph;

   EdgeE;

   VertexV;

   intNv,i;

   

   scanf("%d",&Nv);//读入顶点个数

   Graph=CreateGraph(Nv);//初始化有Nv个顶点但没有边的图

   

   scanf("%d",&(Graph->Ne));//读入边数

   if(Graph->Ne!=0 ){//如果有边

       E= (Edge)malloc(sizeof(structENode));//建立边结点

       //读入边,格式为"起点 终点 权重",插入邻接矩阵

       for(i=0;i<Graph->Ne;i++){

           scanf("%d %d %d",&E->V1,&E->V2&E->Weight);//读进来的时候,编号是从1开始的

           //注意:;如果权重不是整型,Weight的读入格式要改

           E->V1--; E->V2--;//读进来的编号都-1,那就变成起始编号从0开始的了,原本1变成0,2变成1,依次变化

           InsertEdge(Graph,E);//插入边的时候,图默认顶点的编号是从0开始

       }

   }

   //如果顶点有数据的话,读入数据。没有的话这个for循环可以删掉

   for(V=0;V<Graph->Nv;V++)

       scanf(" %c",$(Graph->Data[V]));

   

   returnGraph;

}

问:图的顶点从0开始编号,而本题目中动物从1开始编号。读输入时该如何处理使得图的相关模块可以顺利应用?

答案:E->V1--; E->V2--;

标准的Floyd算法

boolFloyd(MGraphGraph ,WeightTypeD[][MaxVertexNum],Vertexpath[][MaxVertexNum])//返回布尔值(bool)

{

   Vertexi,j,k;

   //初始化

   for(i=0;i<Graph->Nv;i++)

       for(j=0;j<Graph->Nv;j++){

           D[i][j] =Graph->G[i][j];

           path[i][j] =-1;

       }

   

   for(k=0;k<Graph->Nv;k++)

       for(i=0;i<Graph->Nv;i++)

           for(j=0;j<Graph->Nv;j++)

               if(D[i][k] +D[k][j] <D[i][j]){

                   D[i][j] =D[i][k] +D[k][j];

                   if( i==j&&D[i][j]<0)//若发现负值圈,从i出发,走了一圈又回到i,这个最短距离是一个负的值,也对应了一个负值圈

                       returnfalse;//不能正确解决,返回错误标记

                   path[i][j] =k;

               }

   returntrue;//算法执行完毕,返回正确标记

}

在本题中进行的改动部分:

网络异常,图片无法展示
|

目录
相关文章
|
4天前
|
算法 Java
【Java高阶数据结构】图-图的表示与遍历(下)
【Java高阶数据结构】图-图的表示与遍历
13 1
|
4天前
|
存储 算法
数据结构作业4-图
数据结构作业4-图
11 4
|
4天前
|
存储 算法 搜索推荐
【Java高阶数据结构】图补充-拓扑排序
【Java高阶数据结构】图补充-拓扑排序
7 1
|
4天前
|
算法 Java
【Java高阶数据结构】图的最短路径问题(下)
【Java高阶数据结构】图的最短路径问题
6 1
|
4天前
|
算法 Java
【Java高阶数据结构】图的最短路径问题(上)
【Java高阶数据结构】图的最短路径问题
6 1
|
4天前
|
机器学习/深度学习 存储 Java
【Java高阶数据结构】图-图的表示与遍历(上)
【Java高阶数据结构】图-图的表示与遍历
10 2
|
4天前
|
C语言
【C语言/数据结构】排序(快速排序及多种优化|递归及非递归版本)
【C语言/数据结构】排序(快速排序及多种优化|递归及非递归版本)
11 0
|
4天前
|
存储 算法 搜索推荐
数据结构期末复习(5)图
数据结构期末复习(5)图
9 0
|
4天前
|
存储 机器学习/深度学习 移动开发
数据结构 第5 6 章作业 图 哈希表 西安石油大学
数据结构 第5 6 章作业 图 哈希表 西安石油大学
21 0
|
4天前
|
存储 机器学习/深度学习 算法
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
21 1