Zwalnianie pamięci drzewa
Ostatnio zmodyfikowano 2017-05-11 10:18
Anim Temat założony przez niniejszego użytkownika |
Zwalnianie pamięci drzewa » 2017-05-10 11:05:46 Cześć, mam takie pytanie, otóż mam stworzone drzewo, z różnymi węzłami, na podstawie struktury: struct node { wezel * right; wezel * left; int key; wezel() : right( NULL ) , left( NULL ) { } ~wezel(); }
wezel::~wezel() { }
int main() { node * root = NULL; insert( root, tmp_key ); ~node(); }
stworzyłem drzewo poprzez dodanie dynamicznie kilkunastu węzłów. Kończę program, i jak powinien wyglądać destruktor do tej struktury? |
|
croppp |
» 2017-05-10 12:00:08 Po prostu przejdź przez każdy węzeł drzewa i usuwaj go. Możesz wykorzystać algorytm DFS. EDIT: w destruktorze usuwasz węzły left, right Napisane na kolanie w godzinach pracy :> W każdym razie robiłbym w ten sposób: #include <iostream> using namespace std;
struct wezel { wezel * right; wezel * left; int key; wezel() : right( NULL ) , left( NULL ) { } ~wezel(); };
void insert( wezel * r, int tmp_key ); void przejdz_drzewo( wezel * temp );
wezel * root = NULL;
int main() { insert( root, 5 ); insert( root, 6 ); insert( root, 4 ); insert( root, 3 ); insert( root, 8 ); insert( root, 1 ); przejdz_drzewo( root ); cout << "usuwam roota " << root->key << endl; delete root; }
void insert( wezel * r, int tmp_key ) { wezel * temp = r; if( temp == NULL ) { root = new wezel; root->key = tmp_key; } else if( tmp_key <= temp->key && temp->left == NULL ) { temp->left = new wezel; temp->left->key = tmp_key; } else if( tmp_key > temp->key && temp->right == NULL ) { temp->right = new wezel; temp->right->key = tmp_key; } else if( tmp_key <= temp->key ) { temp = temp->left; insert( temp, tmp_key ); } else if( tmp_key > temp->key ) { temp = temp->right; insert( temp, tmp_key ); } }
void przejdz_drzewo( wezel * temp ) { if( temp ) { cout << "Wezel: " << temp->key << endl; przejdz_drzewo( temp->left ); przejdz_drzewo( temp->right ); } }
wezel::~wezel() { if( left != NULL ) { cout << "Usuwam wezel " << left->key << endl; delete left; } if( right != NULL ) { cout << "Usuwam wezel " << right->key << endl; delete right; } }
|
|
j23 |
» 2017-05-10 14:32:12 Nie musisz sprawdzać, czy wskaźnik jest różny od null. delete poradzi sobie z null-pointerem bez problemu. |
|
croppp |
» 2017-05-10 14:43:49 No tak, tylko przy próbie wypisywania, który węzeł jest usuwany odwołam się do NULLa i program się wykrzaczy. Jeśli autor zdecyduje się usunąć ify to niech to zrobic razem z coutami :) |
|
bombatom69 |
» 2017-05-10 19:06:09 Takie rozwiązania, opierające się na "lawinowym" usuwaniu, mają ograniczoną poprawność. Drzewo powinno być stosunkowo odporne ale już w przypadku listy ryzyko otrzymania stack overflow, jest duże.
Wywołujesz destruktor korzenia i on nie skończy pracy dopóki nie zwolni swoich dzieci. Na ich rzecz wywołane zostaną destruktory, które również nie skończą pracy dopóki nie zwolnią swoich dzieci ... i tak do końca struktury.
Jeśli twoje drzewo zacznie się degenerować do listy to z punktu widzenia tego sposobu niczym się nie będzie od niej różnić.
Dlatego lepiej prowadzić destrukcję w klasie drzewo niż w klasie węzeł.
Poza tym, przy lawinowym usuwaniu, DFS nie ma tutaj nic z nim wspólnego, bo takie realizuje automatycznie BFS.
DFS należy właśnie zastosować w konstruktorze drzewa. |
|
j23 |
» 2017-05-11 10:18:09 @croppp, można tak, bez ifów: wezel::~wezel() { cout << "Usuwam wezel " << key << '\n'; delete left; delete right; }
:) |
|
« 1 » |