数据结构面试之八——图的常见操作2之最短路径

简介: (1)从选定的源顶点出发,先选择与该源顶点相连的权值最小且尚未标识过的顶点X,并标识X为True、记录该路径长度;(2)然后比较经过该顶点X与其余顶点相连的路径之和是否小于源顶点到其余顶点的直接路径长度,是,则修改路径长度;否,则保持不变;(3)循环执行(1),直至所有的顶点都标识为True。

数据结构面试之九——图的常见操作2之最短路径

题注:《面试宝典》有相关习题,但思路相对不清晰,排版有错误,作者对此参考相关书籍和自己观点进行了重写,供大家参考。


八、图的常见操作2之最短路径


(一)最短路径核心思想步骤如下:


(1)从选定的源顶点出发,先选择与该源顶点相连的权值最小且尚未标识过的顶点X,并标识X为True、记录该路径长度;


(2)然后比较经过该顶点X与其余顶点相连的路径之和是否小于源顶点到其余顶点的直接路径长度,是,则修改路径长度;否,则保持不变;


(3)循环执行(1),直至所有的顶点都标识为True。


为了便于理解,执行步骤图示如下几个表格。初始图结构表示如下:表格内值为顶点之间的权重,如(Vertex4,Vertex1)=10 代表顶点4与顶点1之间的路径权重为10。



Vertex 0


Vertex 1


Vertex 2


Vertex 3


Vertex 4


Vertex 0


0


16



2


3


Vertex 1



0


5




Vertex 2



3


0




Vertex 3



12



0


7


Vertex 4



10


4


5


0


假定求解从顶点0到其余各顶点的最短路径长度。


前提:初始化操作,将0到各顶点的权重值存储到数组weights[][]中;将最小权重发现标识存储到数组weightFound[]中,并初始化weightFound[0]=true(因为0为源点)。


第1步:查找并选定顶点0到其余各顶点的最小权重值的顶点,且要求查找的点尚未被标识过true。显然,此处选择顶点Vertex3。


算法的执行步骤如下图所示:



Vertex 0


Vertex 1


Vertex 2


Vertex 3


Vertex 4


原始权值


0


16



2


3


选定v3后


修改权重


0


(0->3->1)


14


(0->3->2)



2


(0->3->4)


9


比较取小值


0


14



2


3


标识


True


False


False


True


False



第2步:查找并选定顶点0到其余各顶点的最小权重值的顶点,且该点尚未被标识过true。


显然,此处选择顶点Vertex 4。


算法的执行步骤如下图所示:



Vertex 0


Vertex 1


Vertex 2


Vertex 3


Vertex 4


原始权值


0


14



2


3


选定v4后


修改权重


0


(0->4->1)


13


(0->4->2)


7


(0->4->3)


8


3


比较取小值


0


13


7


2


3


标识


True


False


False


True


True



第3步:查找并选定顶点0到其余各顶点的最小权重值的顶点,且该点尚未被标识过true。


显然,此处选择顶点Vertex 2。


算法的执行步骤如下图所示:



Vertex 0


Vertex 1


Vertex 2


Vertex 3


Vertex 4


原始权值


0


13


7


2


3


选定v2后


修改权重


0


(0->2->1)


10


7


(0->2->3)



(0->2->4)



比较取小值


0


10


7


2


3


标识


True


False


True


True


True



第4步:查找并选定顶点0到其余各顶点的最小权重值的顶点,且该点尚未被标识过true。


显然,此处选择顶点Vertex 1。


算法的执行步骤如下图所示:



Vertex 0


Vertex 1


Vertex 2


Vertex 3


Vertex 4


原始权值


0


10


7


2


3


选定v1后


修改权重


0


10


(0->1->2)


    15


(0->1->3)



(0->1->4)



比较取小值


0


10


7


2


3


标识


True


True


True


True


True



至此,所有标记都为True,比较结束。顶点0到其余各点的最短路径分别如下:


Vertex 0到其余各顶点


Vertex 1


Vertex 2


Vertex 3


Vertex 4


最短路径


10


7


2


3



//inifinity 代表权值无穷大,即不可达。

int g_WeightMatrix[5][5] ={infinity,16,infinity,2,3,

      infinity,infinity,5,infinity,infinity,

      infinity,3,infinity,infinity,infinity,

      infinity,12,infinity,infinity,7,

      infinity,10,4,5,infinity};

template <class vType, int size>

class weightedGraphType : publicgraphType<vType, size>

{

public:

      voidcreateWeightedGraph();

      voidshortestPath(vType vertex);

      voidprintShortestDistance(vType vertex);

protected:

      intweights[size][size];  //权重矩阵

      intsmallestWeight[size]; //源到其他顶点的最短路径

};


1.   创建权重图


创建权重图的时候,我们做了简化处理。只是将给定的权重数组赋值过来了。[此处稍作修改,便可以改为手动输入顶点及邻接边的关系]。图的存储采用邻接矩阵的存储结构。


template <class vType, int size>

voidweightedGraphType<vType,size>::createWeightedGraph()

{

      gSize= size;

      for(int i = 0; i < size; i++)

      {

             smallestWeight[i]= 0;

             for(int j =0; j < size; j++)

             {

                    weights[i][j]= g_WeightMatrix[i][j];

                    cout<< weights[i][j] << "\t";

             }

             cout<< endl;

      }

}

2.      求最短路径(1个源节点到其余结点Dijkstra算法)


template <class vType, int size>

voidweightedGraphType<vType,size>::shortestPath(vType vertex)

{

      intv=0;

      intminWeight;

   

//初始化 0代表到自身,infinity代表不可达.

//从结点vertex到j的权重记录在数组中

      for(intj = 0; j < gSize; j++)

      {

             smallestWeight[j]= weights[vertex][j];

      }

      boolweightFound[size];

      //权重是否应用标识...

      for(intj = 0; j < gSize; j++)

      {

             weightFound[j]= false;            

      }

      weightFound[vertex]= true;   //初始设定

      smallestWeight[vertex]= 0;   //最小权重初始为0或infinity(不可达)

//结束标记——循环一遍(即:所有点都已经标识)。

//循环次数为gSize-2的原因是是vertex节点已经标识为true.

      for(int i = 0; i < gSize-1; i++)

      {

             minWeight= infinity;  

//从所有顶点中寻找权重最小且未被标识的顶点,

//v记录该顶点,minWeight记录权重值。

             for(int j = 0; j < gSize; j++)

             {

                    if(!weightFound[j])

                    {

                           if(smallestWeight[j]< minWeight)

                           {

                                  v= j;

                                  minWeight= smallestWeight[v];

                           }//endif

                    }//endif

             }//endfor j

             //标识点v已用.

             weightFound[v]= true;

   

//利用已经标识的点v,判断经过v点的路径权重+(v->目的)

//权重值是否<已记录的smallestWeight。如果小,则替换;否则,不变。

             for(int j = 0; j < gSize; j++)

             {

                    if(!weightFound[j])

                    {

                           if(minWeight+ weights[v][j] < smallestWeight[j])

                           {

                                  smallestWeight[j]= minWeight + weights[v][j];

                           }

                    }

             }//endfor j(in)

      }//endfor

}

3.      打印最短路径


//打印最短路径 源vertex结点到其余各个结点之间的路径...


template <class vType, int size>

voidweightedGraphType<vType,size>::printShortestDistance(vType vertex)

{

      cout<< "Source vertex: " << vertex << endl;

      cout<< "Shorest distance from source to each vertex" << endl;

      cout<< "Vertex Shortest_Distance" << endl;

      shortestPath(vertex);

      for(int j = 0; j < gSize; j++)

      {

             cout<< setw(4) << j << setw(12) << smallestWeight[j]<< endl;

      }

      cout<< endl;


相关文章
|
3月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
185 3
|
11月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
538 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
【Java集合类面试二十六】、介绍一下ArrayList的数据结构?
ArrayList是基于可动态扩展的数组实现的,支持快速随机访问,但在插入和删除操作时可能需要数组复制而性能较差。
|
8月前
|
存储 人工智能 算法
【C++数据结构——图】最短路径(头歌教学实验平台习题) 【合集】
任务描述 本关任务:编写一个程序,利用Dijkstra算法,实现带权有向图的最短路径。 相关知识 为了完成本关任务,你需要掌握:Dijkst本关任务:编写一个程序,利用Dijkstra算法,实现带权有向图的最短路径。为了完成本关任务,你需要掌握:Dijkstra算法。带权有向图:该图对应的二维数组如下所示:Dijkstra算法:Dijkstra算法是指给定一个带权有向图G与源点v,求从v到G中其他顶点的最短路径。Dijkstra算法的具体步骤如下:(1)初始时,S只包含源点,即S={v},v的距离为0。
117 15
|
11月前
|
算法 前端开发 Java
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
这篇文章总结了单链表的常见面试题,并提供了详细的问题分析、思路分析以及Java代码实现,包括求单链表中有效节点的个数、查找单链表中的倒数第k个节点、单链表的反转以及从尾到头打印单链表等题目。
120 1
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
|
10月前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
算法 Python
逆袭之路!用 Python 玩转图的 DFS 与 BFS,让数据结构难题无处遁形
【7月更文挑战第12天】图的遍历利器:DFS 和 BFS。Python 中,图可表示为邻接表或矩阵。DFS 沿路径深入,回溯时遍历所有可达顶点,适合找路径和环。BFS 层次遍历,先近后远,解决最短路径问题。两者在迷宫、网络路由等场景各显神通。通过练习,掌握这些算法,图处理将游刃有余。
157 3
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
146 1
|
存储 测试技术
【数据结构】操作受限的线性表,栈的具体实现
【数据结构】操作受限的线性表,栈的具体实现
140 5
|
存储 测试技术
【数据结构】操作受限的线性表,队列的具体实现
【数据结构】操作受限的线性表,队列的具体实现
101 4