基于Treap数据结构实现动态图:邻居向量地址存储问题咨询
Hey there, let's tackle your questions about optimizing your TreapNode for dynamic graph storage!
1. Will storing the vector's address reduce the size of TreapNode?
Absolutely. Here's why:
- A
vector<int>object itself (not the data it holds) typically takes up 24 bytes on a 64-bit system (it contains three pointers: to the data buffer, the end of the used data, and the end of the allocated capacity). - If you replace the
vector<int>member with a pointer to avector<int>(i.e.,vector<int>*), that pointer only takes 8 bytes on 64-bit systems. This cuts down the size of each TreapNode significantly, which can improve cache efficiency since more nodes fit into CPU cache at once.
Just keep in mind: you'll now have to manually manage the memory for these vectors (create them when nodes are constructed, delete them when nodes are destroyed) to avoid leaks.
2. How to correctly store and access the vector's address
Your earlier attempt failed because you tried to initialize a member pointer using another non-static member (neighbourNode) directly in the class declaration—this isn't allowed in C++, since the member neighbourNode hasn't been constructed yet when the compiler processes that line.
Here's the proper approach:
Step 1: Modify the TreapNode class
Replace the vector<int> neighbourNode member with a pointer to a vector<int>. Using a vector<int>* is safer than a raw int* because it lets you use all of vector's built-in methods (like push_back, size, etc.) without manual memory management headaches.
class TreapNode { public: int key; int priority; TreapNode* left, *right; vector<int>* neighbourVec; // Pointer to the vector of neighbors // Constructor: Initialize the pointer with a new empty vector TreapNode(int key) : key(key), priority(0), left(nullptr), right(nullptr) { neighbourVec = new vector<int>(); } // Destructor: Clean up the vector to avoid memory leaks ~TreapNode() { delete neighbourVec; } // Disable default copy constructor/assignment to prevent double-free issues TreapNode(const TreapNode&) = delete; TreapNode& operator=(const TreapNode&) = delete; TreapNode* addNode(TreapNode*&, int); void updateNode(TreapNode*&, int, int); };
Step 2: Access and modify the neighbor list
When you need to add a neighbor to a node, use the pointer to call vector methods:
// Inside updateNode, once you've found the target node (searchAddress) searchAddress->neighbourVec->push_back(x);
To read neighbors, you can iterate over the vector just like before:
for (int neighbor : *(searchAddress->neighbourVec)) { // Do something with neighbor }
3. Why your initial attempt threw an error
The line int* neighbourNodeAddress = neighbourNode.data() in the class declaration is invalid because:
- Class member initializers (the ones written directly in the class) can only use compile-time constants or parameters passed to the constructor.
- At the point the compiler processes that line, the
neighbourNodemember hasn't been constructed yet—so it doesn't exist, hence the "neighbourNode未定义" error.
By moving the initialization into the constructor (where neighbourVec is created with new vector<int>()), you ensure the vector exists before you reference it.
内容的提问来源于stack exchange,提问作者tushar

