亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

圖的兩種表示和接口

2019-11-14 09:04:53
字體:
來源:轉載
供稿:網友

常讀常新

這里多分析了三個點: 1. 兩種表示方式在另一個維度的比較; 2. 一種復雜應用場景下的取舍辦法; 3. 經典表示方法之外的黑科技。

眾所周知,在經典的圖論里,圖的兩種表示方式為: 1. 鄰接矩陣; 2. 鄰接表。

先回顧一下,圖是由結點,以及結點之間的邊構成的。結點一般編號為0,1,2,……,然后一條邊由<u, v[,w]>來定義,其中的u和v都是某個結點的編號(如果有w的話,表示這條邊的權重)。

圖還分為有向圖和無向圖,其實本質上并沒區別,可以說一切圖都是有向圖,而無向圖只不過是每條有向邊都存在一條反方向的邊而已(兩個結點可以直接互通,謂之無向,在這里,“方向”表示通行的限制)。

記號聲明

E,表示整張圖的邊(edge)的數量;V,表示整張圖的頂點(vertex)的數量;e,表示某個頂點相鄰的邊的數量。

優缺點分析

先po一張統一的圖以便后續分析:

結點為:0, 1, 2邊為:<0, 1, 10>, <1, 2, 66>, <2, 0, 55>

這張圖很明顯是一個三角形。

鄰接矩陣

顧名思義,這種方式是用一個N*N的矩陣來表示圖,如果存在邊

0 10 00 0 6655 0 0優點:可以在常數時間內得到一條邊的權重;缺點:占用內存多,特別是對于稀疏圖來說;缺點:沒法保證在O(e)時間內遍歷某個結點的所有邊。

稍微解釋一下,對于1,因為矩陣可以隨機存取元素,所以可以在常數時間內知道兩個結點之間是否存在一條邊。 對于2,很明顯矩陣占用的內存是頂點的數量的平方,對于稀疏圖來說,很浪費內存。 對于3,比如想遍歷結點1的所有邊(在這里只有1條),但沒法只訪問1次,而是必須得訪問V(=3)次,才能得出所有與1相鄰的邊。

鄰接表

用矩陣對于稀疏圖來說,太過浪費內存,所以不妨只記錄每個結點相鄰的結點,比如vector<vector<pair<int, int> > > >就是一個鏈表的數組。

用鏈表來表示上面的圖便是:

0 -> [<1, 10>]1 -> [<2, 66>]2 -> [<0, 55>]優點:相對省內存,如果E < N*N的話;優點:可以在O(e)時間內遍歷某個結點的所有邊;缺點:沒法在常數時間內獲取一條邊的權重。

對于1,鄰接鏈表存儲的元素數量等于邊的數量,對于稀疏圖來說,很明顯是節省內存的。 對于2,由于某個結點對應的鏈表就是與它相鄰的所有邊,自然可以在O(e)時間內遍歷完。 對于3,由于是用鏈表存儲的,沒法隨機訪問,所以必須遍歷鏈表來得到具體的某條邊的權重。

取舍

普通情況下,只需要按照上面提到的優缺點便可以輕松取舍,比如稠密圖就用鄰接矩陣啦,稀疏圖并且不需要在常數時間內獲取一條邊的權重的就用鄰接表啦……

但是,在這樣一種較復雜的情況下,該用什么——

既需要在常數時間內獲取一條邊的權重,又需要在O(E)時間內遍歷某個結點的所有邊。

注意,這里不需要省內存了。

回答這個問題之前,可能一個正常人會先問:真的有這樣的場景嗎?

有的,這種需求在圖論算法的實現中比比皆是,比如最近重新寫Dijkstra算法,首先需要在常數時間內獲取某條邊的權重(因為需要用來計算最短路徑);其次,每次一個結點出隊時,我需要遍歷它的所有相鄰的邊,來“疏松”路徑。

那該怎么辦呢?看上去水火不相容???

其實我的解決辦法很簡單,兩種表示法都用,然后各取其長處即可!這樣自然沒法省內存了,不過時空博弈從來如此。

最后面有具體的實例。

一點點黑科技

其實很容易想到其它的數據結構來表示圖,比如用map<pair<int, int>, int>,map的鍵是結點對<u, v>,map的值是該邊的權重。

這樣的數據結構可以在log(E)(注意是大寫的E)的時間內獲取某條邊的權重,但是……沒法獲取某個頂點相鄰的邊,只能用其它的數據結構來保存,比如vector<vector<int> >保存的是所有邊的信息,這里和鄰接表唯一不同的地方就是,沒有保存權重,因為權重是用上述的map來保存。

把這兩者結合起來的好處是,當log(E)普遍遠遠小于e時,這樣做的總體效率會比鄰接表好一些~

有沒有必要搞這樣一個“四不像”出來呢?應該是有的,就是,圖比較稠密,且頂點的數量太大以至于沒法開一個矩陣來存放時!

或許會有更好的solution也說不定。

取舍的做法舉例

舉個例子,我為了調用簡單,把這兩種表示方法都寫成了類,先看看是如何調用的:

int main() { int n, e, u, v, w; cin >> n >> e; AdjacencyMatrix am(n); AdjacencyList al(n); while (e--) { cin >> u >> v >> w; am.insertEdge(u, v, w); al.insertEdge(u, v, w); } int s, t; while (cin >> s >> t) { dijkstra(am, al, s, t); } return 0;}

完整的代碼請移步:http://paste.Ubuntu.com/23929990/。

然后AdjacencyMatrix和AdjacencyList具體是這樣的:

// DirectedGraph.h#ifndef __Directed_Graph_H__#define __Directed_Graph_H__#include <vector>#include <iostream>using namespace std;typedef int weight_t;const weight_t INFINITE = 1e9;class AdjacencyMatrix{public: AdjacencyMatrix(size_t n); int getWeight(size_t u, size_t v) const; void insertEdge(size_t u, size_t v, weight_t w); size_t getNumberOfNode() const;PRivate: vector<vector<weight_t> > data; size_t numberOfNode;};class AdjacencyList{public: AdjacencyList(size_t n); int getWeight(size_t u, size_t v) const; void insertEdge(size_t u, size_t v, weight_t w); const vector<vector<size_t> >& getEdges() const; size_t getNumberOfNode() const;private: size_t numberOfNode; vector<vector<size_t> > edges; vector<vector<weight_t> > weights;};#endif//DirectedGraph.cpp#include "DirectedGraph.h"AdjacencyMatrix::AdjacencyMatrix(size_t n): data(n, vector<weight_t>(n, INFINITE)), numberOfNode(n) {}int AdjacencyMatrix::getWeight(size_t u, size_t v) const { return data[u][v];}void AdjacencyMatrix::insertEdge(size_t u, size_t v, weight_t w) { data[u][v] = w;}size_t AdjacencyMatrix::getNumberOfNode() const { return numberOfNode;}// =====華麗麗的~分隔線======AdjacencyList::AdjacencyList(size_t n): edges(n), weights(n), numberOfNode(n) {}int AdjacencyList::getWeight(size_t u, size_t v) const { for (int i = 0; i < edges[u].size(); ++i) { if (edges[u][i] == v) return weights[u][i]; } return INFINITE;}void AdjacencyList::insertEdge(size_t u, size_t v, weight_t w) { edges[u].push_back(v); weights[u].push_back(w);}const vector<vector<size_t> >& AdjacencyList::getEdges() const { return edges;}size_t AdjacencyList::getNumberOfNode() const { return numberOfNode;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产高清福利视频| 91九色精品视频| 久久精视频免费在线久久完整在线看| 日韩福利在线播放| 欧美极品在线播放| 少妇精69xxtheporn| 亚洲日本中文字幕| 欧美wwwxxxx| 97超碰蝌蚪网人人做人人爽| 最好看的2019的中文字幕视频| 国产成人激情小视频| 国产精品高潮呻吟久久av野狼| 成人精品一区二区三区电影黑人| 国产精品一区二区久久国产| 欧美乱大交xxxxx另类电影| 中文字幕精品在线视频| 久久人人看视频| 亚洲天堂av在线免费观看| 日韩欧美亚洲国产一区| 欧美一二三视频| 欧美尤物巨大精品爽| 欧美日韩国产综合视频在线观看中文| 国产精品免费视频久久久| 爱福利视频一区| 欧美自拍视频在线| 另类天堂视频在线观看| 亲子乱一区二区三区电影| 亚洲91精品在线观看| 亚洲天堂av电影| 日韩免费观看视频| 中文字幕日本欧美| 国产日韩欧美视频在线| 亚洲精品av在线| 国产欧美一区二区三区在线看| 色偷偷亚洲男人天堂| 亚洲一区亚洲二区亚洲三区| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲欧美制服综合另类| 欧美激情乱人伦一区| 91精品国产色综合久久不卡98口| 国产噜噜噜噜久久久久久久久| 精品久久久久久久久国产字幕| 国产精品免费观看在线| 亚洲人成电影网站色xx| 国产精品吴梦梦| 欧美一区二区影院| 欧美性69xxxx肥| 亚洲深夜福利视频| 亚洲高清免费观看高清完整版| 色噜噜亚洲精品中文字幕| 日韩精品亚洲精品| 日韩国产高清视频在线| 国产日韩在线看| 欧美激情中文字幕乱码免费| 国产精品稀缺呦系列在线| 色综合五月天导航| 91久久精品日日躁夜夜躁国产| 精品人伦一区二区三区蜜桃免费| 色综久久综合桃花网| 亚洲精品美女视频| 亚洲一区二区三区在线免费观看| 国产成人综合一区二区三区| 国产精品日韩欧美综合| 国产美女久久精品| 欧美日韩国产一区二区三区| 亚洲自拍偷拍网址| 亚洲欧美色婷婷| 欧美国产日韩xxxxx| 亚洲国产日韩一区| 国产日韩精品入口| 青青草原一区二区| 视频一区视频二区国产精品| 亚洲国产高潮在线观看| 欧美成人h版在线观看| 国产精品91久久久久久| 国产精品免费网站| 国产日本欧美一区二区三区在线| 国产精品黄色影片导航在线观看| 欧美黄色免费网站| 欧美精品在线免费观看| 日韩欧美在线中文字幕| 欧美精品www| 国产+成+人+亚洲欧洲| 久久免费视频网站| 国产精品999999| 欧美高清videos高潮hd| 亚洲自拍偷拍第一页| 精品美女久久久久久免费| 久久琪琪电影院| 国产91在线播放九色快色| 成人黄色激情网| 成人av番号网| 美女福利精品视频| 国内精品400部情侣激情| 日韩av一区二区在线观看| 亚洲欧美日韩精品久久亚洲区| 91久久精品国产91性色| 欧美一级高清免费播放| 日韩在线欧美在线| 久久香蕉精品香蕉| 亚洲影院色无极综合| 911国产网站尤物在线观看| 欧美理论电影在线观看| 日韩av网站电影| 2019av中文字幕| 亚洲大胆人体视频| 成人97在线观看视频| 久久久久久久久中文字幕| 国产精品日日摸夜夜添夜夜av| 九九精品在线观看| 欧美猛男性生活免费| 一区二区欧美激情| 91久久精品日日躁夜夜躁国产| 国产精品扒开腿爽爽爽视频| 亚洲电影免费在线观看| 欧美怡春院一区二区三区| 日韩高清av在线| 亚洲国产精品人久久电影| 亚洲а∨天堂久久精品喷水| 精品久久久久久久久国产字幕| 98午夜经典影视| 欧美黑人一级爽快片淫片高清| 久久亚洲精品一区| 中文字幕精品久久| 欧美综合第一页| 欧美成人第一页| 欧美成人三级视频网站| 一本色道久久88综合日韩精品| 91在线视频成人| 精品福利视频导航| 久久中文字幕一区| 91在线精品视频| 国产精品主播视频| 热99精品只有里视频精品| 国产精品第一区| 最近中文字幕2019免费| 中文字幕欧美精品日韩中文字幕| 欧美一级在线播放| 久久久久国产精品免费网站| 国产亚洲欧洲黄色| 亚洲国产日韩欧美综合久久| 亚洲国产精品悠悠久久琪琪| 国产亚洲欧美一区| 亚洲国产精品悠悠久久琪琪| 欧美极品少妇全裸体| 国产一区二区黑人欧美xxxx| 欧美视频免费在线观看| 91欧美视频网站| 国产精品毛片a∨一区二区三区|国| 按摩亚洲人久久| 日韩欧美国产骚| 国产成人精品视频在线| 久久免费高清视频| 亚洲中国色老太| 欧美一区亚洲一区| 精品久久久久久国产| 国产aⅴ夜夜欢一区二区三区| 欧美小视频在线| 国产69精品99久久久久久宅男| 国产日本欧美一区二区三区| 久久精品视频一| 国产精品免费福利| 亚洲iv一区二区三区| 精品国偷自产在线视频|