2011-02-07 3 views
0

누구나 교체 기능이 작동하지 않는 이유를 알 수 있습니까? 메인이 replace (1,2, list)라고 부른다. 노드를 검색해야하며 노드 값이 1이면 값 2 인 새 노드를 만들어 교체하고 첫 번째 노드에 할당 된 메모리를 확보해야합니다. 나는 (당신의 replace() 기능에 문제가 몇 가지 있습니다c - 연결된 목록 기능 바꾸기

typedef struct iNode 
{ 
    int myInt; 
    struct iNode* next; 
} IntNode, *IntNodePtr; 

IntNodePtr insert(int i, IntNodePtr p) 
{ 
    IntNodePtr newp = malloc(sizeof(struct iNode)); 
    newp->myInt = i; 
    newp->next = p; 
    return newp; 
} 

IntNodePtr delete(int i, IntNodePtr p) 
{ 
    /* End of list check */ 
    if(p == NULL) 
     return NULL; 

    /* Check if current node is the one to delete */ 
    if(p->myInt == i) 
    { 
     IntNodePtr temp; 
     temp = p->next; 

     free(p); 
     return temp; 
    } 

    p->next = delete(i, p->next); 
    return p; 
} 

IntNodePtr replace(int i, int j, IntNodePtr p) 
{ 
    if(p == NULL) 
     return NULL; 

    if(p->myInt == i) 
     insert(j, p->next); 

    free(p); 

    p->next = replace(i, j, p->next); 
    return p; 
} 
+0

목록의 첫 번째 링크를 항상 'replace' 함수에 전달해야합니다. 그렇지 않으면 목록이 깨지게됩니다. 그것은 당신이 지금까지 가지고있는 2 ~ 3 개의 대답을위한 것입니다. 나는 아마 그 가정을 알고 있지만 ... – JimR

답변

0

. (그것은) 당신의 마지막 질문에 나에게 잘 보였다.

  1. 당신은 insert() 때를 = 전화를 밖으로 그것을 알아낼 수 없습니다 당신은 i이있는 노드를 찾을 수 있지만 기본적으로 삽입하는 새로운 노드가 그래서 당신이 그것에 p를 설정해야합니다 새로운 p이다 (어떤 insert() 반환). 새 노드에 아무것도 할 수 없습니다.

  2. p을 비우고 바로 pnext 필드를 값으로 설정하려고합니다. p이 가리키고있는 위치가 유효하지 않으므로 그렇게하지 말아야합니다. 임시 변수를 사용하여 이전 p을 저장해야 나중에 자유롭게 사용할 수 있습니다. 이전 상태의 일부가되도록 실제로 교체하는 경우에만 수행해야합니다.

나는 그것을 포함해야한다고 생각한다. 기본적으로 변경 사항은 다음과 같습니다 마크 지적

/* if the current node contains the int I'm looking for... */ 
if(p->myInt == i) 
{ /* ... the current node needs to be replaced */ 
    /* save the current node to delete later (2) */ 
    IntNodePtr oldNode = p; 

    /* insert a new node making it the new current node (1) */ 
    p = insert(j, oldNode->next); 

    /* free the old node (2) */ 
    free(oldNode); 
} 
/* and so on */ 
+0

코드를 편집하고 jeff를 게시 할 수 있습니까? 메신저는 혼란스럽고 혼란스럽고 여전히 이해하지 못합니다. 나는 이전 함수도 좋아했지만, 함수는 변경 불가능해야하고, 내 함수는 변경 가능해야한다. – mikecavs

+0

@mike : 너 거의 먹었어. 기본적으로'delete()'함수와 비슷한 구조를가집니다. 바라건대 지금은 훨씬 더 명확 해지기를 바랍니다. –

+0

Jeff, 정말 고마워. 마침내 어디서 잘못 됐는지 보게. 때로는 코드가 잘못된 이유를 이해하기 전에 올바른 코드를 살펴 봐야 할 때가 있습니다. – mikecavs

0

으로, 당신의 free(p) 정의되지 않은 동작을 일으 킵니다. 따라서, 다음 문

p->next = replace(i, j, p->next); 

는 포인터 값으로 p->next을 할당하려고하기 때문에 무효가됩니다 만, p->next 메모리 위치 자체가 정의되어 있지 않습니다.

하지만 왜이 재귀 함수를 재귀 적으로 만들었습니까? 간단한 while 루프로 충분합니다.

IntNodePtr replace(int i, int j, IntNodePtr p) { 
    if(p == NULL) 
     return NULL; 
    IntNodePtr prevPtr = NULL; 
    while(p){ 
     if(p->myInt == i){ 
      IntNodePtr temp = insert(j, p->next); 
      if(prevPtr) 
       prevPtr->next = temp; 
      free(p); 
      break; 
     } 
     prevPtr = p; 
     p = p->next; 
    } 
} 

그리고 당신은 새로 만든 노드로 이전 노드를 연결되지 않기 때문에 당신은 잘못뿐만 아니라 당신의 삽입 기능을 사용하고 있습니다.