mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-10 22:46:07 +00:00
deploy
This commit is contained in:
@@ -3489,7 +3489,7 @@ G & = \{ V, E \} \newline
|
||||
\end{aligned}
|
||||
\]</div>
|
||||
<p><img alt="链表、树、图之间的关系" src="../graph.assets/linkedlist_tree_graph.png" /></p>
|
||||
<p align="center"> Fig. 链表、树、图之间的关系 </p>
|
||||
<p align="center"> 图:链表、树、图之间的关系 </p>
|
||||
|
||||
<p>那么,图与其他数据结构的关系是什么?如果我们把「顶点」看作节点,把「边」看作连接各个节点的指针,则可将「图」看作是一种从「链表」拓展而来的数据结构。<strong>相较于线性关系(链表)和分治关系(树),网络关系(图)的自由度更高,从而更为复杂</strong>。</p>
|
||||
<h2 id="911">9.1.1. 图常见类型<a class="headerlink" href="#911" title="Permanent link">¶</a></h2>
|
||||
@@ -3499,7 +3499,7 @@ G & = \{ V, E \} \newline
|
||||
<li>在有向图中,边具有方向性,即 <span class="arithmatex">\(A \rightarrow B\)</span> 和 <span class="arithmatex">\(A \leftarrow B\)</span> 两个方向的边是相互独立的,例如微博或抖音上的“关注”与“被关注”关系。</li>
|
||||
</ul>
|
||||
<p><img alt="有向图与无向图" src="../graph.assets/directed_graph.png" /></p>
|
||||
<p align="center"> Fig. 有向图与无向图 </p>
|
||||
<p align="center"> 图:有向图与无向图 </p>
|
||||
|
||||
<p>根据所有顶点是否连通,可分为「连通图 Connected Graph」和「非连通图 Disconnected Graph」。</p>
|
||||
<ul>
|
||||
@@ -3507,11 +3507,11 @@ G & = \{ V, E \} \newline
|
||||
<li>对于非连通图,从某个顶点出发,至少有一个顶点无法到达。</li>
|
||||
</ul>
|
||||
<p><img alt="连通图与非连通图" src="../graph.assets/connected_graph.png" /></p>
|
||||
<p align="center"> Fig. 连通图与非连通图 </p>
|
||||
<p align="center"> 图:连通图与非连通图 </p>
|
||||
|
||||
<p>我们还可以为边添加“权重”变量,从而得到「有权图 Weighted Graph」。例如,在王者荣耀等手游中,系统会根据共同游戏时间来计算玩家之间的“亲密度”,这种亲密度网络就可以用有权图来表示。</p>
|
||||
<p><img alt="有权图与无权图" src="../graph.assets/weighted_graph.png" /></p>
|
||||
<p align="center"> Fig. 有权图与无权图 </p>
|
||||
<p align="center"> 图:有权图与无权图 </p>
|
||||
|
||||
<h2 id="912">9.1.2. 图常用术语<a class="headerlink" href="#912" title="Permanent link">¶</a></h2>
|
||||
<ul>
|
||||
@@ -3525,7 +3525,7 @@ G & = \{ V, E \} \newline
|
||||
<p>设图的顶点数量为 <span class="arithmatex">\(n\)</span> ,「邻接矩阵 Adjacency Matrix」使用一个 <span class="arithmatex">\(n \times n\)</span> 大小的矩阵来表示图,每一行(列)代表一个顶点,矩阵元素代表边,用 <span class="arithmatex">\(1\)</span> 或 <span class="arithmatex">\(0\)</span> 表示两个顶点之间是否存在边。</p>
|
||||
<p>如下图所示,设邻接矩阵为 <span class="arithmatex">\(M\)</span> 、顶点列表为 <span class="arithmatex">\(V\)</span> ,那么矩阵元素 <span class="arithmatex">\(M[i][j] = 1\)</span> 表示顶点 <span class="arithmatex">\(V[i]\)</span> 到顶点 <span class="arithmatex">\(V[j]\)</span> 之间存在边,反之 <span class="arithmatex">\(M[i][j] = 0\)</span> 表示两顶点之间无边。</p>
|
||||
<p><img alt="图的邻接矩阵表示" src="../graph.assets/adjacency_matrix.png" /></p>
|
||||
<p align="center"> Fig. 图的邻接矩阵表示 </p>
|
||||
<p align="center"> 图:图的邻接矩阵表示 </p>
|
||||
|
||||
<p>邻接矩阵具有以下特性:</p>
|
||||
<ul>
|
||||
@@ -3537,7 +3537,7 @@ G & = \{ V, E \} \newline
|
||||
<h3 id="_2">邻接表<a class="headerlink" href="#_2" title="Permanent link">¶</a></h3>
|
||||
<p>「邻接表 Adjacency List」使用 <span class="arithmatex">\(n\)</span> 个链表来表示图,链表节点表示顶点。第 <span class="arithmatex">\(i\)</span> 条链表对应顶点 <span class="arithmatex">\(i\)</span> ,其中存储了该顶点的所有邻接顶点(即与该顶点相连的顶点)。</p>
|
||||
<p><img alt="图的邻接表表示" src="../graph.assets/adjacency_list.png" /></p>
|
||||
<p align="center"> Fig. 图的邻接表表示 </p>
|
||||
<p align="center"> 图:图的邻接表表示 </p>
|
||||
|
||||
<p>邻接表仅存储实际存在的边,而边的总数通常远小于 <span class="arithmatex">\(n^2\)</span> ,因此它更加节省空间。然而,在邻接表中需要通过遍历链表来查找边,因此其时间效率不如邻接矩阵。</p>
|
||||
<p>观察上图可发现,<strong>邻接表结构与哈希表中的「链地址法」非常相似,因此我们也可以采用类似方法来优化效率</strong>。例如,当链表较长时,可以将链表转化为 AVL 树或红黑树,从而将时间效率从 <span class="arithmatex">\(O(n)\)</span> 优化至 <span class="arithmatex">\(O(\log n)\)</span> ,还可以通过中序遍历获取有序序列;此外,还可以将链表转换为哈希表,将时间复杂度降低至 <span class="arithmatex">\(O(1)\)</span> 。</p>
|
||||
|
||||
Reference in New Issue
Block a user