你選擇的數據結構將需要很多多餘的內存,動態分配在堆上。 std::map
和std::string
將爲每個單個條目分配一塊內存(加上它自己的開銷)。 std::string
也將爲該字符串分配一段內存。
這很舒服,在很多情況下完全可以。但對於大型數據結構來說並不好。
最後,你有一個映射,其中包含指針(它本身被逐一分配)給集合,它包含指向字符串的指針(它本身被逐個分配),它包含指向實際字符串緩衝區的指針。
您的實際問題是動態分配產生的開銷。在大多數平臺上,堆分配只需要一個額外的16字節內存來管理堆(儘管數字會有所不同)。
我建議,通過以下方式,你重新定義你的圖形:
// a list of node names, its index (a size_t) is used in the following data structures
// - alternatively, you may use an std::map<int,std::string> here, to simplify the
// "index" to "name" lookup...
typedef size_t NodeId;
typedef std::vector<std::string> NodeList;
// an edge
typedef std::pair<NodeId,NodeId> Edge;
// or alternatively:
struct Edge {
NodeId from, to;
};
// a plain list of edges
typedef std::vector<Edge> EdgeList;
,或者下面的數據結構可以爲您的使用情況更容易。它類似於你的榜樣,但更緊湊的內存中表示:
// a list of node names, its index (a size_t) is used in the following data structures
typedef size_t NodeId;
typedef std::vector<std::string> NodeList;
typedef std::vector<NodeId> NodeIdList;
// a map from one node to its adjacent nodes
typedef std::map< NodeId, NodeIdList > Graph;
編輯:添加和使用NodeIdList
...
如果這仍然消耗了太多的內存,那麼你應該考慮關於將數據保存在磁盤上並按需加載。
如果你的節點名稱是常量,那麼你還應該考慮某種string-table,這是一種更緊湊的字符串數據在內存中的表示形式。但這是相當低級的東西。
嘗試先使用更好的數據結構!
也許某種鏈表結構?或者也許是一個稀疏的鄰接列表 - 你只是存儲邊緣。 – 2011-12-26 05:38:41
你可以發佈你現在使用的數據結構嗎?另外,大圖中有多少個節點和邊? – 2011-12-26 05:43:03