多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
> 引用:[https://blog.csdn.net/zjw\_python/article/details/85158998](https://blog.csdn.net/zjw_python/article/details/85158998) [toc] # 图的存储 存储分为以下方法: - 邻接矩阵 - 邻接表 - 十字链表 - 邻接多重表 ## 邻接矩阵 用 `二维数组` 的方式来存储图结构。 - 无向图 ![](https://img.kancloud.cn/76/eb/76eb4d4eca469db8f6400f86e7761736_492x718.png) 缺点: 1. 太浪费空间 2. 图中的顶点经常是动态的,需要添加和删除,二维数组尺寸是固定的不方便 - 有向图 ![](https://img.kancloud.cn/bc/41/bc4174129bba3418a50bc147445bfd17_472x718.png) - 有向带权图 ![](https://img.kancloud.cn/7e/45/7e45162cd53057c6c51893372e24aa9c_1246x422.png) ## 邻接表 `数组+链表` 进行存储。 图的每一个顶点都是一个头节点,其后连接着该顶点能够直接达到的相邻顶点。 ![](https://img.kancloud.cn/ff/a6/ffa66da7e9b5a08d1f1f4842a6d32942_832x330.png) ## 邻接多重表 邻接多重表是 `无向图` 的一种存储方式。 ![](https://img.kancloud.cn/47/67/47670f4d3f5a577a10e2a1dcf56cdefd_1462x548.png) ## 逆邻接表 每一个顶点作为链表的头节点,后继节点所存储的是 `能够直接达到该顶点` 的相邻顶点。 ![](https://img.kancloud.cn/13/c2/13c2f1d9f1d510dc148ca05d65779fc4_1542x596.png) ## 十字链表 每一个顶点作为链表的头节点,都可以有两个链: 1. 所有这个节点可以到达的节点 2. 所有可以到达该节点的节点 ![](https://img.kancloud.cn/3d/bd/3dbd8dca0cfb3defc23c4bb517cef377_1598x1412.png) # 代码实现-邻接表 ~~~ class Graph { constructor () { this.vertices = []; // 用来存放图中的顶点 this.adjList = new Set(); // 用来存放图中的边 } // 向图中添加一个新顶点 addVertex (v) { if (!this.vertices.includes(v)) { this.vertices.push(v); this.adjList.set(v, []); } } // 向图中添加a和b两个顶点之间的边 addEdge (a, b) { // 如果图中没有顶点a,先添加顶点a if (!this.adjList.has(a)) { this.addVertex(a); } // 如果图中没有顶点b,先添加顶点b if (!this.adjList.has(b)) { this.addVertex(b); } this.adjList.get(a).push(b); // 在顶点a中添加指向顶点b的边 this.adjList.get(b).push(a); // 在顶点b中添加指向顶点a的边 } // 获取图的vertices getVertices () { return this.vertices; } // 获取图中的adjList getAdjList () { return this.adjList; } toString() { let s = ''; this.vertices.forEach((v) => { s += `${v} -> `; this.adjList.get(v).forEach((n) => { s += `${n} `; }); s += '\n'; }); return s; } } ~~~