我認爲在這種情況下,最好的辦法是使用預分配雙向鏈表...
// Untested code... just to give the idea
struct Node
{
int data;
Node *prev, *next;
static Node *first, *last, *free;
// Allocates a new node before the specified node or
// at the end of the list if before is NULL
static Node *alloc(int data, Node *before)
{
// Check the free list first
Node *n = free;
if (!n)
{
// There are no free nodes... allocate a bunch of them
Node *page = new Node[1000];
for (int i=0; i<999; i++)
{
page[i].next = &page[i+1];
}
page[999].next = NULL;
n = free = &page[0];
}
// Update the free list
free = n->next;
// Link the new node to neighbors
n->next = before;
n->prev = before ? before->prev : last;
if (n->prev) n->prev->next = n; else first = n;
if (n->next) n->next->prev = n; else last = n;
// Initialize it
n->data = data;
return n;
}
// Deallocates a node, placing it in the free list for reuse
static dealloc(Node *n)
{
if (n)
{
// Remove from double chain
if (n->next) n->next->prev = n->prev; else last = n->prev;
if (n->prev) n->prev->next = n->next; else first = n->next;
// Add to free list
n->next = free; free = n;
}
}
};
當你需要分配一個節點只需要調用Node::alloc
傳遞數據和在哪裏放節點。當你需要釋放它時,只需調用node dealloc。
節點在「頁面」中分配並在釋放後重新使用。這樣可以最大限度地減少對內存管理器的調用次數,並且可以顯着加快速度。
雙鏈接結構永遠不需要移動存儲器中的現有節點(因此不需要調整指針)。對元素重新排序也很容易,例如添加Node::moveTo(Node *before)
方法。
這種方法的缺點是訪問第n個元素給定的索引是O(n)操作。
爲什麼不使用std :: vector? – xeon111
你必須在哪裏添加和刪除元素?正面,背面,可能在任何地方?從概念上講,刪除元素將總是重新編號後續元素。 –