Andrzej Borucki programista
Temat: Jak sobie poradzić bez wskaźników?
Przykład: implementacja drzew binarnych w C++ i JavieWstawianie elementów:
Jeżeli drzewo jest puste wstawiamy element, który staje się korzeniem. Gdy jest niepuste, od korzenia
wyszukujemy odpowiednie odpowiedniego miejsce, następnie wstawiamy go jako następnik lewy
(gdy mniejszy) lub prawy (gdy większy).
Gdy już istnieje - zgłaszamy błąd lub możemy inaczej obsługiwać - np. listę o takim samym kluczu,
czy też zamiast sprawdzać czy mniejszy, sprawdzać czy nie większy przy szukaniu.
Usuwanie elementów:
Wyszukujemy węzeł, który mamy usunąć. Gdy nie znaleźliśmy - błąd.
Przypadki:
- gdy ma jeden następnik lub nie ma wcale ma następników - należy połączyć poprzednika
z tym następnikiem który jest (albo ustawić poprzednika na NULL gdy nie ma wcale następników)
i usunąć element
- jeśli ma dwa następniki - sytuacja się komplikuje...
W C++:
struct BSTNode
{
int key;
BSTNode *left, *right;
BSTNode(int k = NULL)
{
left = right = NULL;
key = k;
}
};
W C++ bardzo pomocny jest wskaźnik na wskaźnik, można np. zrobić wskaźnik na pole root albo na elem->left czy elem->right:
void Insert(int key)
{
if (root == NULL)
root = new BSTNode(key);
else
{
BSTNode *node = root;
BSTNode **field; //wskażnik na pole BSTNode: left lkub right
do
{
if (node->key == key) throw "Klucz musi byc unikalny!";
if (key < node->key) field = &node->left;
else field = &node->right;
node = *field;
} while (node != NULL);
assert(node == NULL);
*field = new BSTNode(key);
}
}
void Delete(int key)
{
BSTNode *node = root;
BSTNode **field = &root;
while (node != NULL)
{
if (node->key == key) break;
if (key < node->key) field = &node->left;
else field = &node->right;
node = *field;
}
if (node == NULL) throw "Nie znaleziono klucza do usuniecia!";
if (node->left == NULL || node->right == NULL)
{
BSTNode **second; //może być wskaźnikiem na NULL lub nie
if (node->left == NULL) second = &node->right; else second = &node->left;
*field = *second;
}
else
{
tu trudniejszy przypadek
}
}
A jak to zrobić w Javie? class BSTNode, klasa jest referencją, ale jak referencję na roota, lub na pole left lub right?