数据结构第六周笔记——图(上2)(慕课浙大版本--XiaoYu)

简介: 图的应用实例及小白知识专场

6.3 应用实例:拯救007

voidSave007(GraphG)

{

   for(eachVinG){

       if(!visited[V] &&FirstJump(V)){//这个FirstJump(V)是007第一跳有没有可能从孤岛跳到V上有没有可能,有且没踩过就跳上去

           answer=DFS(V);//or BFS(V)

           if(answer==YES) break;0

       }

   }

   if(answer==YES) output("Yes");

   elseoutput("No");

}

DFS算法

voidDFS(VertexV)

{

   visited[V] =true;//表示鳄鱼头踩过了

   for(V的每个邻接点W)

       if(!visited[W])

           DFS(W);//递归

}

改良版本

voidDFS(VertexV)

{

   visited[V] =true;//表示鳄鱼头踩过了

   if(IOsSafe(V)) answer=YES;

   else{

   for(eachWinG )

       if(!visited[W] &&Jump(V,W)){//可以从V jump跳到这个w上面,作用是算V到W之间的距离是不是小于007可以跳跃最大距离

         answer=DFS(W);//递归

           if(answer==YES) break;

       }

   }

       returnanswer;

}

6.4 应用实例:六度空间(Six Degrees of Separation)

理论:

  1. 你和任何一个陌生人之间所间隔的人不会超过6个
  2. 给定社交网络图,请对每个节点计算符合"六度空间"理论的结点占结点总数的百分比

算法思路

1.对每个节点进行广度优先搜索

2.搜索过程中累计访问的节点数

3.需要记录"层",仅计算6层以内的节点数

   

voidSDS()

{

   for(eachVinG){

       count+=BFS(V);

       Output= (count/N);

   }

}

//结合最初的BFS

   voidBFS(VertexV)

{

   visited[V] =true;count=1;

   Enqueue(V,Q);//压到队列里

   while(!IsEmpty(Q)){

       V=Dequeue(Q);//每次循环弹出一个节点

       for(V的每个邻接点W)

           if(!visited[W]){//没有访问过的去访问将其压入队列中

               visited[W] =true;

               Enqueue(W,Q);count++;

           }

   }returncount;

}

另外的解决方案

intBFS(VertexV)

{

   vistex[V] =true;count=1;

   level=0;last=V;

   Enqueue(V,Q);

   while(!IsEmpty(Q)){

       V=Dequeue(Q);

       for( V的每个邻接点W)

           if(!visited[W]){

               visited[W] =true;

               Enqueue(W,Q);count++;

               tail=W;

           }

       if(V==last ){

           level++;last=tail;

       }

   }

   returncount++;

}

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

小白专场:如何建立图:C语言实现

小白BG.1邻接矩阵表示的图结点的结构

typedefstructGNode*PtrToGNode;//PtrToGNode是指向GNode的一个指针

structGNode{

intNv;//顶点数

intNe;//边数

WeightTypeG[MaxVertexNum][MaxVertexNum];

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

};

typedefPtrToGNodeMGraph;//以邻接矩阵存储的图类型。定义为指向节点的指针。因为要用到的时候一个指针远远比一整个图来的快捷

小白BG.2邻接矩阵表示的图——初始化

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

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

MGraphCreateGraph(intVertexNum)//VertexNum这个顶点数真的是整数,

{

   VertexV , W;//我们在说V跟W的时候不是在说整数,而是顶点

   MGraphGraph;

   

   Graph= (MGraph)malloc(sizeof(structGNode));

   Graph->Nv=VertexNum;

   Graph->Ne=0;

   

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

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

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

   Graph->G[V][M] =0;//或者INFINITY,表示这两个顶点之间是没有边的

   

   returnGraph

}

小白BG.3邻接矩阵表示的图——插入边

typedefstructENode*PtrToENode;

structENode{

   VertexV1,V2;//有向边<V1,V2>,V1V2两个顶点一个出发点一个终点

   WeightTypeWeight;//权重,有权图才需要。权重的类型是WeightType

};

typedefPtrToENodeEdge;

voidInsertEdge(MGraphGraph,EdgeE)

{

   //插入边<V1,V2>,这是一条边

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

   

   //无向图的话还需要一条边(一共两条),<V2,V1>

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

}

小白BG.4邻接矩阵表示的图——建立图

完整的建立一个MGraph

输入格式

  1. Nv Ne
  2. V1 V2 Weight
  3. ......

MGraphBuildGraph()

{

   MGraphGraph;

   

   

   

   

   

   scanf("%d",&Nv);

   Graph=CreateGraph(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);

       InsertEdge(Graph,E);

       }

   }

   //如果顶点有数据的话,读入数据

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

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

   returnGraph;

}

简易建法

intG[MAXN][MAXN],Nv,Ne;//声明为全局变量

voidBuildGraph()

{

   inti,j,v1,v2,w;

   

   scanf("%d",&Nv);

   //CreateGraph

   for(i=0;i<Nv;i++)

       for(j=0;j<Nv;j++)

           G[i][j] =0;//或INFINITY,把矩阵所有元素先初始化为0或者无穷大

   scanf("%d",&Ne);

   for(i=0;i<Ne; i++){

       scanf("%d %d %d",&v1,&v2,&w);

       //InsertEdge

       G[v1][v2] =w;

       G[v2][v1] =w;

   }

}

小白BG.5邻接表表示的图结点的结构

邻接表:G[N]为指针数组,对应矩阵每一行一个链表,只存非0元素

typedefstructGNode*PtrToGNode;

structGNode {

   intNv;//顶点数

   intNe;//边数

   AdjListG;//邻接表

};

typedefPtrToGNodeLGraph;

//以邻接表方式存储的图类型

//AdjList是自己定义的

typedefstructVnode{

   PtrToAdjVNodeFirstEdge;

   DataTypeData;//存顶点的数据

}AdjList[MaxVertexNum];//AdjList是邻接表类型

typedefstructAdjVNode*PtrToAdjVNode;

structAdjVNode{

   VertexAdjV;//邻接点下标,定义为整型

   WeightTypeWeight;//边权重

   PtrToAdjVNodeNext;

};

小白BG.6邻接表表示的图——建立图

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

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

LGraphCreateGraph(intVertexNum)

{

   VertexV,W;

   LGraphGraph;

   

   Graph= (LGraph)malloc(sizeof(structGNode));

   Graph->Nv=VertexNum;

   Graph->Ne=0;

   

   

   //没有边的意思是每个顶点跟着的那个链表都是空的

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

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

   Graph->G[V].FirstEdge=NULL;

   

   returnGraph;

}

向LGraph中插入边

voidInsertEdge(LGraphGraph,EdgeE)

{

   PtrToAdjVNodeNewNode;

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

   //为V2建立新的邻接点

   NewNode= (PtrToAdjVNode)malloc(sizeof(structAdjNode));

   NewNode->AdjV=E->V2;

   NewNode->Weight=E->Weight

       //将V2插入到V1的表头

       NewNode->Next=Graph->G[E->V1].FirstEdge;

   Graph->G[E->V1].FirstEdge=NewNode;

   

   //-------------------若是无向图,还需插入边<V2,V1>------------------

       //为V1建立新的邻接点

   NewNode= (PtrToAdjVNode)malloc(sizeof(structAdjNode));

   NewNode->AdjV=E->V1;

   NewNode->Weight=E->Weight

       //将V2插入到V1的表头

       NewNode->Next=Graph->G[E->V2].FirstEdge;

   Graph->G[E->V2].FirstEdge=NewNode;

}

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

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

完整建立一个LGraph

LGraphBuildGraph()

{

   LGraphGraph;

   ...............                    

}


目录
相关文章
|
6月前
|
存储 算法
数据结构===图
数据结构===图
|
5月前
|
算法 Python
逆袭之路!用 Python 玩转图的 DFS 与 BFS,让数据结构难题无处遁形
【7月更文挑战第12天】图的遍历利器:DFS 和 BFS。Python 中,图可表示为邻接表或矩阵。DFS 沿路径深入,回溯时遍历所有可达顶点,适合找路径和环。BFS 层次遍历,先近后远,解决最短路径问题。两者在迷宫、网络路由等场景各显神通。通过练习,掌握这些算法,图处理将游刃有余。
66 3
|
5月前
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
47 1
|
6月前
|
存储 算法
【单向链表】数据结构——单向链表的介绍与代码实现&笔记
【单向链表】数据结构——单向链表的介绍与代码实现&笔记
|
6月前
|
存储 算法
【树】数据结构——树和二叉树的概念&笔记
【树】数据结构——树和二叉树的概念&笔记
|
6月前
|
算法 Java 索引
12.12_黑马数据结构与算法笔记Java
12.12_黑马数据结构与算法笔记Java
50 1
|
5月前
|
存储 算法 C语言
软考中级之数据库系统工程师笔记总结(二)数据结构与算法
软考中级之数据库系统工程师笔记总结(二)数据结构与算法
38 0
|
6月前
|
存储 算法 Linux
【内核链表】数据结构——深入理解内核链表的概念和操作&笔记
【内核链表】数据结构——深入理解内核链表的概念和操作&笔记
【循环链表】数据结构——单向循环链表和双向循环链表操作&笔记
【循环链表】数据结构——单向循环链表和双向循环链表操作&笔记
|
6月前
|
存储
数据结构学习记录——如何建立图(邻接矩阵、邻接表-图节点的结构、创建并初始化、插入变、完整图的建立)
数据结构学习记录——如何建立图(邻接矩阵、邻接表-图节点的结构、创建并初始化、插入变、完整图的建立)
90 0