簡體   English   中英

基本的C ++圖形實現

[英]Rudimentary C++ Graph Implementation

我正在為我正在學習的C ++類進行圖形實現。 到目前為止,這是我想出的:

struct Edge {
    int weight;
    Vertex *endpoints[2]; // always will have 2 endpoints, since i'm making this undirected
};

struct Vertex {
    int data; // or id
    list<Edge*> edges;
};

class Graph {
public:
    // constructor, destructor, methods, etc.
private:
    list<Vertex> vertices;
};

目前有點粗糙,但我想我在想...我是否缺少基本知識? 目前看來有點太簡單了,通常這意味着我在設計錯誤。

我的想法是,圖只是一個頂點列表,它具有一個列表邊,該列表邊將具有一個邊列表,其中有兩個頂點端點。

除了要放入圖中的某些功能(例如:最短距離,大小,添加頂點等)之外,我在這些結構/類的基本實現中是否缺少某些功能?

有時,您需要設計類似的東西,而現在尚不清楚最有用的實現和數據表示形式是什么(例如,是否更好地存儲點集合或邊緣集合,或兩者兼而有之?),您會一直遇到這個問題。

例如,您可能會發現第一個構造函數並不是您真正想要的。 讓Graph類創建Vertices可能比傳遞它們更容易。

退后一步,先處理客戶端代碼,而不是在類本身內部工作並玩猜謎游戲。 例如,您將要創建一個Graph對象,添加一些點,以某種方式將這些點與邊緣連接,等等。

您從客戶端進行的調用順序將自然而然地發生,函數本身的參數也將自然而然地出現。 了解了客戶端的外觀后,您可以開始自己實現功能,並且將更加清楚實際的實現方式是什么。

有關您的實施的評論:

圖是對象的集合,其中一些對象對是相關的。 因此,您當前的實現方式是一種可行的實現方式。 您可以對對象及其之間的關系進行建模。

當前實現的優點主要是沿邊緣的恆定查找時間和通用性。 查找時間:如果要訪問節點kn個鄰居,可以在固定時間內完成。 通用性:這代表了幾乎任何人可能想到的圖形,特別是如果您用對象(或Template )替換weightdata的數據類型。

當前實現的缺點是它可能會慢於理想的速度。 跨越邊緣看起來很便宜,但仍然需要兩跳而不是一跳(節點->邊緣->節點)。 此外,使用邊緣列表將使您花費O(d)的時間查找特定的邊緣,其中d是圖形的度數。 (您對指針的依賴還要求該圖適合一台計算機的內存;您在使用Facebook的圖或美國道路網時會遇到麻煩。在這一點上,我懷疑並行計算是否是您所關心的。)


實現圖形時的注意事項:

但是,您的問題詢問這是否是最佳方法。 這是一個困難的問題,因為圖表的幾種特定品質可以發揮作用。

邊緣信息:如果頂點的關聯方式無關緊要(即,邊緣沒有權重或值),則使用邊緣對象毫無意義; 這只會讓你慢下來。 相反,每個頂點只能保留指向其鄰居的指針的列表,或者保留其鄰居的ID的列表。

構造:正如您在注釋中所注意到的那樣,當前的實現要求在添加邊之前必須具有可用的頂點。 總的來說,這是對的。 但是您可能想在添加邊時動態創建頂點。 這可以使構造看起來更整潔,但是如果頂點具有非恆定的查找時間,則將花費更多時間。 如果在構造圖形之前知道所有頂點,則最好先顯式創建它們,然后再顯式創建邊緣。

密度:如果圖是稀疏的(即,每個頂點的邊數大約是常數),那么鄰接表也是一種不錯的方法。 但是,如果密集,則使用鄰接矩陣通常可以提高性能。 每個頂點按順序擁有所有其他頂點的列表,因此訪問任何邊都是恆定時間操作。

算法:您打算在圖形上解決哪些問題? 幾種著名的 圖形 算法根據圖形的表示方式具有不同的運行時間。


附錄:

看一下這個問題,以獲得更多可能有助於您的注釋: 圖形實現C ++

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM