2011-11-26 5 views
0

많은 노력 끝에 필자는 연결된 목록에서 일부 노드를 삭제하는 기능을 함께 사용했습니다. 그러나 관심의 대상에서 첫 번째 노드, 즉 머리를 목록에서 삭제하는 방법을 알고 싶습니다.링크 된 목록에서 노드 삭제

내 프로그램에서 삭제할 편지를 요구합니다. 예를 들면 다음과 같습니다. Hello가 목록에 저장되면 사용자가 H를 입력하여 삭제합니다. 이제 목록이 ello 입니다. 코드가있는 순간 프로그램이 H가 삭제되고 머리가없고 프로그램이 분명히 충돌합니다. 목록을 찾으러 가야할 곳을 알지 못합니다.

다음은 현재 구현입니다.이 코드를 수정하는 방법에 대한 단서 또는 힌트 (머리 모양을 그대로 유지하고 싶습니다)를 통해 헤드 노드 삭제가 많은 도움이 될 것입니다.

편집 : 응답에서 당신이 인수를 변경할 때

FullList DeleteNode(FullList temp, char c) { 
FullList remember; 
FullList ptr; 
while (temp.head->c != c) { 
    remember.head = temp.head; 
    temp.head = temp.head->next; 
} 
ptr.head = temp.head->next; 
free(temp.head); 
remember.head->next = ptr.head; 
return temp; 
} 

int main(void) { 
FullList List; 
char c, s; 
List.head = NULL; 

while ((c=getchar()) != '.') { 
    List = addToEnd(List, c); 
} 
scanf(" %c", &s); 
List = DeleteNode(List, s); 
while (List.head != NULL) { 
    printf("%c", List.head->c); 
    List.head = List.head->next; 
} 
return 0; 
} 

typedef struct List { 
char c; 
struct List *next; 
}List; 

typedef struct { 
List *head; 
List *tail; 
}FullList; 

List *insertList(char c, List *t1) { 
    List *t = (List*)calloc(1, sizeof(List)); 
    t->c = c ; 
    t->next = t1; 
return t; 
} 

FullList addToEnd(FullList c, char element) { 
if (c.head == NULL) { 
    c.head = c.tail = insertList(element, NULL); 
}else { 
    c.tail->next = insertList(element, NULL); 
    c.tail = c.tail->next; 
} 
return c; 
} 

void DeleteNode(FullList temp, char c) { 
FullList remember; 
FullList ptr; 
while (temp.head->c != c) { 
    remember.head = temp.head; 
    temp.head = temp.head->next; 
} 
ptr.head = temp.head->next; 
free(temp.head); 
remember.head->next = ptr.head; 
} 


int main(void) { 
FullList List; 
char c, s; 
List.head = NULL; 

while ((c=getchar()) != '.') { 
    List = addToEnd(List, c); 
} 
scanf(" %c", &s); 
DeleteNode(List, s); 
while (List.head != NULL) { 
    printf("%c", List.head->c); 
    List.head = List.head->next; 
} 
return 0; 
} 

답변

1

기존 코드를 변경하지 않으면이를 수행 할 수 없습니다.

FullList 구조체를 DeleteNode() 함수에 전달하고 있습니다. 즉, 구조체에 대한 변경 사항은 main에 표시되지 않습니다.이 함수는 복사본이됩니다.

당신은 포인터를 받아 DeleteNode()을 변경해야 할 것 :을 호출 할 때 다음

void DeleteNode(FullList *temp, char c) 

main() 당신이 할 것 :

DeleteNode(&List, s); 

을 이렇게하면 temp->head의 값을 변경할 수 있습니다 귀하의 기능 및 그것은 다시 볼 수 있습니다. main()

temp->head = temp->head->next; 
,

편집 : 당신이 필요합니다 논리는 다음과 같습니다 temp->head->c == c

  • 예라면은, 임시 포인터 *previous에 다른 temp->head->next
  • 지정 temp->headtemp->head를 교체 할 경우

    • 확인 확인합니다. 포인터 *currenttemp->head->next을 지정하십시오. 목록을 반복하면서 두 포인터를 움직입니다.current->c에서 일치 항목을 발견하면 current->nextprevious->nextfree()current 노드로 할당하십시오.
  • +0

    내가 제안한대로 코드를 수정했지만 이제는 입력 된 문자까지 모든 것을 삭제합니다. ie Abcde, input c, de가 인쇄됩니다. – PnP

    +0

    가능한 경우 제 편집문을 참조하십시오. 포인터를 사용하는 대신 FullList를 반환했지만 동일한 결과를 얻으면 입력 할 때까지 모든 내용이 삭제됩니다. – PnP

    +0

    @ user1048116 - 이제'temp-> head'의 값을 바꾸기 위해 설명했습니다. 나는 당신을 위해 숙제를하지 않았습니다;) 머리에서 시작하여 일치하는 논리를 만들어야합니다. 힌트를 얻으려면''previous ''와''current'' 두 개의 포인터가 필요합니다. 당신은 머리에서 시작하여 이전 노드와 현재 노드를 추적하고 'current-> c'에서 당신의 매칭을 찾아야합니다. 삭제할 노드를 찾으면'current-> next '를'previous-> next'에 할당하고'current' 노드를'free'해야합니다. 이 함수에서 아무 것도 반환 할 필요가 없습니다. 포인터를 통해 구조체를 수정하려는 것입니다. –

    1

    는, 지금 DeleteNode 내부의 방법 이하, 단지 외부가 아닌 하나를 로컬 변수를 변경하는 기능.

    당신이 중 하나는 짓을 수정 발신자에 볼 수, 또는 그것을 로컬 하나를 수정하고 반환되도록 포인터 DeleteNodeFullList을 통과해야하고, 발신자는 목록에 반환 FullList를 할당해야합니다.

    어쨌든 DeleteNode의 변경 사항이 발신자에게 표시되어야합니다.

    +0

    위의 답변에서 편집 및 의견을 참조하십시오. :) – PnP

    +0

    @ user1048116 브라이언 로치 (Brian Roach)가 말했듯이 두 개의 포인터 (하나는 현재와 하나는 이전 포인터, 다음 포인터는 수정해야 함)를 사용하거나'temp.head-> temp.head-> c 대신'next-> c'를 사용하고,'head-> c '가 원하는 문자 인 특별한 경우를 갖는다. –

    +0

    조언을 주셔서 감사합니다. 실제로 검색된 항목이 헤드 노드가되고 ELSE 절의 나머지 코드가 덤프되는 경우 IF 문을 추가하여 현재 코드로 작업하도록했습니다. – PnP