이것은 진정으로 저를 곤경에 빠뜨렸습니다. 도시 이름으로 정렬 된 도시의 이진 검색 트리가 있습니다. 도시에는 인구와 GPS 좌표도 포함됩니다. 도시 이름 또는 도시 좌표로 트리에서 노드를 제거 할 수 있기를 원합니다. 이름이 잘 작동하지만 GPS 좌표가 작동하지 않습니다.BST에서 노드를 삭제할 때 오류가 발생했습니다.
GPS로 노드를 제거하면 이진 트리를 인쇄하려고 할 때 스택 오버플로가 발생합니다. 아래는 내 코드 중 일부입니다. 같은 삭제 방법을 사용하고 있기 때문에 좌표로 삭제해도 이름으로 삭제해도 정상적으로 작동하는 것을 이해할 수는 없습니다.
정확한 오류는 "처리되지 않은 0x013214D6 예외 : 0xC00000FD : 스택 오버플로 (매개 변수 : 0x00000001, 0x00152FFC)"입니다. 이것은 좌표로 삭제 한 후 내 인쇄 기능에서 발생하지만 이름으로 삭제하는 경우에는 발생하지 않습니다.
bool BinaryTree::DeleteByName(string city)
{
if (GetRoot() != NULL)
{
return (DeleteByName(GetRoot(), city));
}
return false;
}
TreeNode* BinaryTree::DeleteByName(TreeNode *node, string city)
{
if (node == NULL)
{
return node;
}
else if (city < node->Data.name)
{
node->Left = DeleteByName(node->Left, city);
}
else if (city > node->Data.name)
{
node->Right = DeleteByName(node->Right, city);
}
else
{
if (node->Left == NULL && node->Right == NULL)
{
delete node;
node = NULL;
}
else if (node->Left == NULL)
{
TreeNode* temp = node;
node = node->Right;
delete temp;
}
else if (node->Right == NULL)
{
TreeNode* temp = node;
node = node->Left;
delete temp;
}
else
{
cout << "Else";
TreeNode* temp = MinPtr(node->Right);
node->Data = temp->Data;
node->Right = DeleteByName(node->Right, temp->Data.name);
}
}
return node;
}
bool BinaryTree::DeleteByCoord(pair<double, double> coords)
{
if (GetRoot() == NULL)
{
return false;
}
else
{
return DeleteByCoord(GetRoot(), coords);
}
}
bool BinaryTree::DeleteByCoord(TreeNode* node, pair<double, double> coords)
{
bool result;
if (node == NULL)
{
return false;
}
else
{
if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
{
return (DeleteByName(node, node->Data.name));
}
result = DeleteByCoord(node->Left, coords);
if (result == true)
{
return result;
}
return DeleteByCoord(node->Right, coords);
}
}
void BinaryTree::Insert(City city)
{
TreeNode* temp = new TreeNode(city);
if (GetRoot() == NULL)
{
root = temp;
}
else
{
Insert(temp, GetRoot());
}
}
void BinaryTree::Insert(TreeNode* toAdd, TreeNode* addHere)
{
if (toAdd->Data < addHere->Data)
{
if (addHere->Left != NULL)
{
Insert(toAdd, addHere->Left);
}
else
{
addHere->Left = toAdd;
}
}
else if (toAdd->Data > addHere->Data)
{
if (addHere->Right != NULL)
{
Insert(toAdd, addHere->Right);
}
else
{
addHere->Right = toAdd;
}
}
}
void BinaryTree::InOrderTraversal(TreeNode* node)
{
if (node != NULL)
{
InOrderTraversal(node->Left);
cout << node->Data << endl;
InOrderTraversal(node->Right);
}
}
void BinaryTree::InOrderTraversal()
{
InOrderTraversal(GetRoot());
}
TreeNode* BinaryTree::GetRoot()
{
return root;
}
TreeNode* BinaryTree::MinPtr(TreeNode* node)
{
while (node->Left != NULL)
{
node = node->Left;
}
return node;
}
그래서 지금 삭제 한 노드를 가리키는 포인터가 아무 것도 가리키지 않고 오류를 일으키는 것입니까? 삭제할 노드와 삭제할 노드를 추적하는 방법을 만드는 가장 좋은 방법은 부모입니까? – crazyeyes
@crazyeyes 아무 말도하지 않고 가비지를 말하며 그러한 메모리에 액세스하는 것은 정의되지 않은 동작입니다. 그런 것. 또는 탐색하지 않고 부모 노드를 삭제할 수 있습니다. 나는. if (city == node-> Left-> Data.name) { 노드 삭제 -> 왼쪽 -> 데이터; 삭제 노드 -> 왼쪽; node-> Left = NULL; } 오른쪽에 대해서도 마찬가지입니다. – VeminZ
감사합니다. – crazyeyes