Удаление пользовательского двусвязного списка
Свойство списка: один указатель указывает на следующий узел, а другой - на любой произвольный узел в списке.
Состав
struct node
{
int val;
node* link[2];
node(int x);
~node();
};
node :: node(int x)
{
val = x;
link[0] = NULL;
link[1] = NULL;
}
node :: ~node()
{
delete(link[0]);
delete(link[1]);
}
Учебный класс
class List
{
node *head, *cloneHead;
node *stack[100];
int childIndex[2][100];
int stptr;
public:
List();
~List();
void createList(int[] , int[][2], int );
int createListStruct(node*);
void createCloneList();
void clone();
void printClone();
};
Создание списка
void List::createList(int a[], int child[][2], int size)
{
node* linkedList[size];
for(int i=0;i<size;i++)
{
linkedList[i] = new node(a[i]);
}
head = linkedList[0];
for(int i=0;i<size;i++)
{
for(int j=0;j<2;j++)
{
if(child[i][j]!=-1)
{
linkedList[i]->link[j] = linkedList[child[i][j]];
}
}
}
}
Главный
int main()
{
int a[]={10,1,3,7,2,8,20};
int child[][2] = {{1,4},{1,2},{3,-1},{6,5},{6,5},{-1,0},{5,5}};
int size = sizeof(a)/sizeof(a[0]);
List L;
L.createList(a,child,size);
L.clone();
L.printClone();
return 0;
}
в нормальных условиях деструктор работает отлично, но для списка с вышеупомянутым свойством List его сбой
например:
Узел: 1
Ссылка 1: Узел 2
Ссылка 2: Узел 3
Узел: 2
Ссылка 1: Узел 3
Ссылка 2: Узел 1
в вышеприведенном случае к тому времени, когда деструктор достигнет Link2 Node2, который указывает на узел 1, узел 1 уже удален, поэтому код выдает ошибку сегментации.
Я придумал: иметь массив уникальных узлов в списке и удалять по одному
Есть ли другой способ сделать это?
2 ответа
2 альтернативы вашему списку идей (которые кажутся нормальными)
Для каждого узла ведите список родителей. Когда узел удаляется, установите для всех родителей указатели на этот узел, чтобы
nullptr
, Вы можете безопасно удалитьnullptr
так часто, как вам нравится.Если ваш график представляет собой дерево (т.е. без циклов), вы можете использовать подсчет ссылок, используя либо общие указатели, либо unique_pointers
Вы можете использовать shared_ptr, и они освободят память, когда последний указатель будет уничтожен или переназначен. Единственное, что вам нужно помнить, - это избегать циклов, поэтому для произвольного узла используйте вместо этого слабый_птр.
struct node; // forward declaration
struct node
{
int val;
shared_ptr<node> next;
weak_ptr<node> other;
};