2012-11-05 2 views
0

이진 검색 트리에서 노드를 제거하는 기능을 구현 중입니다. 함수의 프로토 타입이 설정되어 있으며 변경할 수 없습니다. 학교 과제 임. 내 코드 : 나는 삭제하고 노드에 연결된 지점이없는 경우이진 검색 트리 노드 삭제

typedef struct tBSTNode { 
    char Key;                 
    struct tBSTNode * LPtr;         
    struct tBSTNode * RPtr; 
} *tBSTNodePtr; 

void BSTDelete (tBSTNodePtr *RootPtr, char K) { 
    tBSTNodePtr *tmp; 

    if (*RootPtr != NULL) { 
    if (K < (*RootPtr)->Key) 
     BSTDelete(&(* RootPtr)->LPtr, K); 
    else if (K > (*RootPtr)->Key) 
     BSTDelete(&(* RootPtr)->RPtr, K); 
    else { 
      if ((* RootPtr)->LPtr == NULL) { 
       /* there is only right branch or none*/ 
       tmp = RootPtr; 
       *RootPtr = (* RootPtr)->RPtr; 
       free(*tmp); 
       *tmp = NULL; 
      } 
      else if ((* RootPtr)->RPtr == NULL) { 
       /* there is only left branch or none*/ 
       tmp = RootPtr; 
       *RootPtr = (* RootPtr)->LPtr; 
       free(*tmp); 
       *tmp = NULL; 
      } 
      else 
       /* there are both branches, but that is for another topic*/ 
     } 
    } 
} 

이 코드는 단지의 경우 제대로 작동합니다. * tmp = NULL에 문제가있을 것으로 예상합니다. 라인과 다른 지점에 내 주소를 잃고 있지만 다른 라인에이 라인이 포함되어 있지 않으면 나는 SEGFAULT를 얻고 있으며 그 이유를 알아 내려고합니다.

편집 :

확인은, 지금은 실수가 어디에 있는지 알고있다. 그것은 어리석은 실수이다, 나는 사용해야했다 tBSTNodePtr tmp; 대신 tBSTNodePtr * tmp;

답변

0

삭제에 대한 논리는 당신이 필요한 노드를 삭제하지만 노드

if ((* RootPtr)->LPtr == NULL) { 
       /* there is only right branch or none*/ 
       tmp = RootPtr; 
       *RootPtr = (* RootPtr)->RPtr; 
       free(*tmp); 
       *tmp = NULL; 
       insert(RootPtr); //insert the child node again in the tree 
      } 
+0

불행히도 나는 insert()와 같은 다른 함수를 호출 할 수 없으므로 표시된 코드 만 사용해야합니다. – skornos

1

당신이 포인터를 사용하여 문제가의 자식 루트를 추가하지 않는이 코드에서

if ((* RootPtr)->LPtr == NULL) { 
       /* there is only right branch or none*/ 
       tmp = RootPtr; 
       *RootPtr = (* RootPtr)->RPtr; 
       free(*tmp); 
       *tmp = NULL; 
      } 

잘못된 것입니다. sometype *ptr이 있고이 ptr이 일부 공간을 차지하는지 확인하면 (ptr!=NULL)이라고 적습니다. *ptr은 값 자체를 참조합니다 (예 : 구조체). C.에서 포인터 유형에 대해 자세히 알아보기

+0

예 C에서 포인터를 사용하는 개념을 알고 있습니다. 당신이 볼 수있는대로 그것을 사용하고 있습니다.하지만 포인터 논리에 문제가있어 아무것도 대답하지 못합니다. – skornos

+0

오, 실례합니다. 나는 typedef에서 '*'를 알아 차리지 못했다. –

+0

나는 내가 알아 냈다고 생각해. 그것은 잘못된 논리입니다. 왼쪽이나 오른쪽 자녀가없는 경우, 양쪽 ifs를 입력하고 두 번 무언가를 무료로합니다. 아래에 언급 된 내용은 매우 옳은 것이며 질문의 열쇠입니다. 하지만 당신의 프로그램이 더 잘 작동하도록'&& (* RootPtr) -> otherside! = NULL '을 조건에 추가해야한다고 생각합니다. –