Есть способ избежать этого. На самом деле вам вообще не нужно отслеживать все указатели в одном месте, потому что сами Node
являются структурой данных.
РЕДАКТИРОВАТЬ: Только что увидел ваш комментарий Objective-C.
Node
должен иметь (синтаксис Objective-C):
// the actual info at this list index
@property (retain) id ptr;
@property (retain) Node *previous;
@property (retain) Node *next;
И тогда ваш DLL
класс - это просто класс с:
@property (retain) Node *first;
@property (retain) Node *last;
@property (assign) NSUInteger count;
Это все, что тебе нужно. Для вставки или удаления узла требуется перетасовка указателя и настройка count
, а доступ осуществляется последовательно с любого конца.
add:(Node*)newNode
будет буквально:
[newNode setPrevious:[self last]];
[[self last] setNext:newNode];
[self setLast:newNode];
[self setCount:[self count]+1];
.. тогда как add:(Node*)newNode atIndex:(NSUInteger)index
будет немного сложнее:
if(index > self.count)
{
// maybe throw an exception or something
} else if(index == self.count) // just do the normal add
{
[self add:newNode];
return;
} else if(index == 0) { // front-insert is also easier
[newNode setNext:[self first]];
[[self first] setPrevious:newNode];
[self setFirst:newNode];
[self setCount:[self count]+1];
return;
}
// maybe do an extra check to see if it's quicker to search from the end
Node *currentLocation = [self first];
NSUInteger idx;
for(idx = 0; i < (index - 1); ++idx)
{
currentLocation = [currentLocation next];
}
Node *previousNode = currentLocation; // store a reference to the previous node
currentLocation = [currentLocation next]; // now at the point we want to insert
[previousNode setNext:newNode];
[newNode setPrevious:previousNode];
[newNode setNext:currentLocation];
[currentLocation setPrevious:newNode];
[self setCount:[self count]+1];