2017-01-19 1 views
2

현재 재귀를 사용하여 수행중인 찾기 및 제거 기능을 수정하려고합니다. 그러나 케이스 2가 끝나면 케이스 0 또는 케이스 1로 연결되는지 식별하는 방법에 대해 문제가 있습니다.이진 검색 트리 찾기 및 제거 [C++]

다음은 내가 수행하려고 시도하는 간단한 설명입니다. 사례 2 (두 자녀) - 오른쪽 하위 트리를 최소로 바꾸면 대소 문자가 구분됩니다. the algorithm에 따르면

bool findAndRemove(const Type& v) 
{ 
    return findAndRemove(root, nullptr, v); 
} 

bool findAndRemove(Node<Type> *fr, Node<Type> *parent, const Type& v) const 
{ 
    if (fr == nullptr) 
    { 
     return true; 
    } 

    if (v < fr->element) 
    { 
     return findAndRemove(fr->left, fr, v); 
    } 
    else if (v > fr->element) 
    { 
     return findAndRemove(fr->right, fr, v); 
    } 
    else 
    { 
     switch (GetChildren(fr)) 
     { 
     case 0: 
      if (parent->left == fr) 
      { 
       parent->left = nullptr; 
       delete fr; 
      } 
      else 
      { 
       parent->right = nullptr; 
       delete fr; 
      } 
      break; 
     case 1: 
      if (parent->left == fr) 
      { 
       if (fr->left != nullptr) 
       { 
        parent->left = fr->left; 
        delete fr; 
       } 
       else 
       { 
        parent->left = fr->right; 
       } 

      } 
      else 
      { 
       if (fr->right != nullptr) 
       { 
        parent->right = fr->right; 
        delete fr; 
       } 
       else 
       { 
        parent->right = fr->left; 
       } 
      } 
      break; 
     case 2: 
     { 
      Node<Type> * swap = fr->right; 
      while (swap->left != nullptr) 
      { 
       swap = swap->left; 
      } 

      Type temp = fr->element; // 30 
      temp = swap->element; // 35 
      swap->element = fr->element; // 30 
      fr->element = temp; 

      //temp = swap->element; 
      //swap->element = temp; 
      //temp = fr->element; 
      break; 
     } 
     } 
    } 
    return false; 
} 
+0

'swap'에는 왼쪽 자식이 없습니다. 그것에는 0 명의 아이들이 있습니다 * iff * 그것은 올바른 아이가 없습니다. 그것은 아이가 1 명 * iff * 아이가 있습니다. 하지만 왜 신경 써야합니까? 그냥'findAndRemove'를 호출 할 수 없습니까? 더 나아가 자체 제거 기능을 자체 기능으로 분리하십시오. 참고 사항 : 루트를 삭제하라는 메시지가 표시되면 알고리즘이 실패합니다. –

답변

2

:

  • 오른쪽 하위 트리에 최소 값을 찾을 수 있습니다;
  • 제거 할 노드의 값을 발견 된 최소값으로 바꿉니다. 자, 오른쪽 하위 트리에 중복이 들어 있습니다!
  • 중복을 제거하려면 오른쪽 하위 트리에 remove를 적용하십시오. swap 점을 그 권리 서브 트리의 최소 노드 코드에서

, 그래서 당신은이 노드에 findAndRemove 함수를 호출하는 경우, 당신은 간단하게 제거 할 수 있습니다.

{ 
    // STEP 1: find a minimum value in the right subtree; 
    Node<Type> * swap = fr->right; 
    while (swap->left != nullptr) 
    { 
     swap = swap->left; 
    } 

    // STEP 2: replace value of the node to be removed with found minimum. 
    fr->element = swap->element; 

    // STEP 3: apply remove to the right subtree to remove a duplicate. 
    // Here you should call 'findAndRemove' on 'swap' node 
    break; 
} 
+0

혼란스러워합니다. 더 자세한 내용을 설명해 주시겠습니까? – EzioBahin

+0

@EzioBahin 처음 두 단계는 이미 완료되었습니다. 오직 세 번째 만 받아 들여야합니다. 세 번째 예제는 2 단계를 적용한 후 최소 노드 (즉, 'swap' 노드)가 중복이된다고 말합니다. 따라서이 중복 노드 (즉,'swap' 노드)를 제거 할 수 있습니다. 승인? 이 노드에서 함수를 호출하면됩니다. –