数据结构与算法之图结构,2024年最新Python大厂面试题来袭

(五)数据结构与算法之树结构基础

(六)数据结构与算法之二叉树大全

(七)数据结构与算法之Huffman tree(赫夫曼树 / 霍夫曼树 / 哈夫曼树 / 最优二叉树)

(八)数据结构与算法之多路查找树(2-3树、2-3-4树、B树、B+树)

(九)数据结构与算法之图结构

十大经典算法

(一)数据结构与算法之冒泡排序(含改进版)

(二)数据结构与算法之选择排序(含改进版)

(三)数据结构与算法之插入排序(含改进版)

(四)数据结构与算法之希尔排序

(五)数据结构与算法之归并排序

(六)数据结构与算法之快速排序

(七)数据结构与算法之堆排序

(八)数据结构与算法之计数排序

(九)数据结构与算法之桶排序

(十)数据结构与算法之基数排序

图的基本概念

========================================================================

(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的。

常用术语

| 术语 | 含义 |

| — | — |

| 顶点 | 图中的某个结点 |

| 边 | 顶点之间连线 |

| 相邻顶点 | 由同一条边连接在一起的顶点 |

| 度 | 一个顶点的相邻顶点个数 |

| 简单路径 | 由一个顶点到另一个顶点的路线,且没有重复经过顶点 |

| 回路 | 出发点和结束点都是同一个顶点 |

| 无向图 | 图中所有的边都没有方向 |

| 有向图 | 图中所有的边都有方向 |

| 无权图 | 图中的边没有权重值 |

| 有权图 | 图中的边带有一定的权重值 |

图的结构很简单,就是由顶点 V 集和边 E 集构成,因此图可以表示成 G = (V,E)

无向图

若顶点 Vi 到 Vj 之间的边没有方向,则称这条边为无向边 (Edge) ,用无序偶对 (Vi,Vj) 来表示。如果图中任意两个顶点之间的边都是无向边,则称该图为无向图 (Undirected graphs)

如:下图就是一个无向图,由于是无方向的,连接顶点 A 与 D 的边,可以表示无序队列(A,D),也可以写成 (D,A),但不能重复。顶点集合 V = {A,B,C,D};边集合 E = {(A,B),(A,D),(A,C)(B,C),(C,D),}

在这里插入图片描述

有向图

用有序偶<Vi,Vj>来表示,Vi 称为弧尾 (Tail) , Vj称为弧头 (Head)。 如果图中任意两个顶点之间的边都是有向边,则称该图为有向图 (Directed grahs)

如:下图就是一个有向图。连接顶点 A 到 D 的有向边就是弧,A是弧尾,D 是弧头, <A, D>表示弧, 注意不能写成<D,A>。其中顶点集合 V = { A,B,C,D}; 弧集合 E = {<A,D>,<B,A>,<B,C>,<C,A>}

在这里插入图片描述

注意:无向边用小括号 “()” 表示,而有向边则是用尖括号"<>"表示

有权图

有些图的边或弧具有与它相关的数字,这种与图的边或弧相关的数叫做权 (Weight) 。这些权可以表示从一个顶点到另一个顶点的距离或耗费。这种带权的图通常称为网 (Network)。

如下图

在这里插入图片描述

图的存储结构及实现

===========================================================================

图结构的常见的两个存储方式: 邻接矩阵 、邻接表

邻接矩阵


在这里插入图片描述图中的 0 表示该顶点无法通向另一个顶点,相反 1 就表示该顶点能通向另一个顶点

先来看第一行,该行对应的是顶点A,那我们就拿顶点A与其它点一一对应,发现顶点A除了不能通向顶点D和自身,可以通向其它任何一个的顶点

因为该图为无向图,因此顶点A如果能通向另一个顶点,那么这个顶点也一定能通向顶点A,所以这个顶点对应顶点A的也应该是 1

虽然我们确实用邻接矩阵表示了图结构,但是它有一个致命的缺点,那就是矩阵中存在着大量的 0,这在程序中会占据大量的内存。此时我们思考一下,0 就是表示没有,没有为什么还要写,所以我们来看一下第二种表示图结构的方法,它就很好的解决了邻接矩阵的缺陷

代码实现

  • 顶点类

public class Vertex {

private String value;

public Vertex(String value) {

this.value = value;

}

public String getValue() {

return value;

}

public void setValue(String value) {

this.value = value;

}

@Override

public String toString() {

return value;

}

}

  • 图类

public class Graph {

private Vertex[] vertex; //顶点数组

private int currentSize; //默认顶点位置

public int[][] adjMat; //邻接表

public Graph(int size) {

vertex = new Vertex[size];

adjMat = new int[size][size];

}

//向图中加入顶点

public void addVertex(Vertex v) {

vertex[currentSize++] = v;

}

//添加边

public void addEdge(String v1, String v2) {

//找出两个点的下标

int index1 = 0;

for (int i = 0; i < vertex.length; i++) {

if (vertex[i].getValue().equals(v1)) {

index1 = i;

break;

}

}

int index2 = 0;

for (int i = 0; i < vertex.length; i++) {

if (vertex[i].getValue().equals(v2)) {

index2 = i;

break;

}

}

//表示两个点互通

adjMat[index1][index2] = 1;

adjMat[index2][index1] = 1;

}

}

  • 测试类

public class Demo {

public static void main(String[] args) {

Vertex v1 = new Vertex(“A”);

Vertex v2 = new Vertex(“B”);

Vertex v3 = new Vertex(“C”);

Vertex v4 = new Vertex(“D”);

Vertex v5 = new Vertex(“E”);

Graph g = new Graph(5);

g.addVertex(v1);

g.addVertex(v2);

g.addVertex(v3);

g.addVertex(v4);

g.addVertex(v5);

//增加边

g.addEdge(“A”, “B”);

g.addEdge(“A”, “C”);

g.addEdge(“A”, “E”);

g.addEdge(“C”, “E”);

g.addEdge(“C”, “D”);

for (int[] a : g.adjMat) {

System.out.println(Arrays.toString(a));

}

}

}

  • 结果值

[0, 1, 1, 0, 1]

[1, 0, 0, 0, 0]

[1, 0, 0, 1, 1]

[0, 0, 1, 0, 0]

[1, 0, 1, 0, 0]

邻接表


邻接表 是由每个顶点以及它的相邻顶点组成的

在这里插入图片描述

如上图:图中最左侧红色的表示各个顶点,它们对应的那一行存储着与它相关联的顶点

  • 顶点A 与 顶点B 、顶点C 、顶点E 相关联

  • 顶点B 与 顶点A 相关联

  • 顶点C 与 顶点A 、顶点D 、顶点E 相关联

  • 顶点D 与 顶点C 相关联

  • 顶点E 与 顶点A 、顶点C 相关联

图的遍历方式及实现

===========================================================================

从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历

在图结构中,存在着两种遍历搜索的方式,分别是 广度优先搜索深度优先搜索

广度优先搜索


广度优先遍历(BFS):类似于图的层次遍历,它的基本思想是:首先访问起始顶点v,然后选取v的所有邻接点进行访问,再依次对v的邻接点相邻接的所有点进行访问,以此类推,直到所有顶点都被访问过为止

BFS和树的层次遍历一样,采取队列实现,这里添加一个标记数组,用来标记遍历过的顶点

在这里插入图片描述

执行步骤

  • 1、先把 A 压入队列,然后做出队操作,A 出队

  • 2、把 A 直接相关的顶点 ,B、F 做入队操作

  • 3、B 做出队操作,B 相关的点 C、I、G 做入队操作

  • 4、F 做出队操作,F 相关的点 E 做入队操作

  • 5、C 做出队操作,C 相关的点 D 做入队操作

  • 6、I 做出队操作(I 相关的点B、C、D 都已经做过入队操作了,不能重复入队)

  • 7、G 做出队操作,G 相关的点 H 做入队操作

  • 8、E 做出队操作…

  • 9、D 做出队操作…

  • 10、H 做出队操作,没有元素了

代码实现

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
img

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-fzxVqMdu-1711093824117)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值