2012-07-17 3 views
1

링크 된 목록을 되돌리려 고했지만 다음 함수를 실행할 때마다 마지막 요소 만 가져옵니다. 예를 들어 목록에 이전에 11,12,13이 포함되어있는 경우 기능을 실행 한 후, 당신의 루프 가드가 그 시작이 null 보장하지 않습니다 내 코드링크 된 목록을 되돌릴 수 없습니다.


void reverselist() 
{ 
    struct node *a,*b,*c; 
    a=NULL; 
    b=c=start; 

    while(c!=NULL) 
    { 
     c=b->next; 
     b->next=a; 
     a=b; 
     b=c; 
    } 
    start=c; 
} 

답변

0

c는 도우미 포인터입니다. 당신이 루프에서 현재 위치에 그것을 할 수있을 때

void reverselist() 
{ 
    struct node *a, *b, *c; 
    a=NULL; 
    b=start; 
    while(b!=NULL) 
    { 
     c=b->next 
     b->next=a; 
     a=b 
     b=c 
    } 
    start=a; 
} 
1
  1. 에서 버그를 지적 만 13 친절 포함?
  2. 시작을 사용하여 목록의 첫 번째 요소를 식별하지 못하면 사용중인 변수가 여전히 마지막 요소 인 첫 번째 요소를 가리키고 있습니다.

    struct node* prepend(struct node* root, int value) 
    { 
        struct node* new_root = malloc(sizeof(struct node)); 
        new_root->next = root; 
        return new_root; 
    } 
    
    struct node* reverselist(struct node* inlist) 
    { 
        struct node* outlist = NULL; 
    
        while(inlist != NULL) { 
         struct node* new_root = prepend(outlist, inlist->value); 
         outlist = new_root; 
         inlist = inlist->next; 
        } 
    
        return outlist; 
    } 
    

    이 테스트를하지 않은,하지만 당신은 그것의 생각을 파악 같아요 :

0

나는 다음은 앞에 추가 기능을 만들고, 할 것이다. 아무 것도 설명하지 않는 변수 이름 일 수도 있지만이 방법이 더 깨끗하고 실제로 일어난 일을 더 쉽게 이해한다고 생각합니다.

편집 :

내가 인플레 이스 그것을하지 않는 이유 질문이있어, 그래서 여기 답변 해 드리겠습니다 :

  1. 당신은 올바른 위치 그것을 할 수 있습니까? 원래의 목록을 계속 사용 하시겠습니까?
  2. inplace해야합니까? malloc이 시간 소모적입니까/이것이 코드에서 성능 측면에서 중요한 부분입니까? 기억하십시오 : 조기 최적화는 모든 악의 뿌리입니다.

이것은 첫 번째 구현입니다. 그것은 작동해야하며 최적화되지 않아야합니다. 또한이 구현을 고려하기 전에 작성된 테스트가 있어야하며 테스트가 통과 될 때까지 느리고 최적화되지 않은 구현을 유지해야하며 사용하기에 느려야한다는 사실을 입증해야합니다.

통과 테스트가 있고 구현 속도가 느린 것으로 입증되면 코드를 최적화하고 테스트를 변경하지 않고 테스트를 통과해야합니다.

또한 답변이 필요한 작업이 있습니까? 되돌리기 전에 메모리를 할당하는 방법은 하나의 할당 호출 만 있으면되므로 성능이 향상 될 것입니다.

이런 식으로 모든 사람이 행복해지면 더 깨끗한 코드를 사용하고 Bob 삼촌이 산탄 총으로 문에 나타나지 않도록 할 수 있습니다.

+0

왜 메모리를 할당? – JimR

+0

글쎄, 당신의 목록에 addAtTail/addAtHead 유형의 호출이 있다면, 하나의 목록을 거꾸로 읽고, 새 목록을 추가하고, 이전 목록을 삭제()하는 것은 기존 목록을 0/1 항목으로 잘라내는 것을 생각하는 것보다 쉽습니다. 코너 케이스 등. 그것은 게으르고 비효율적입니다. 그렇습니다. 그러나 작업이 드물고 시간이 본질적이지 않은 경우에 그것을 고백합니다. –

+0

@MartinJames : 한 번 쓰고 스 니펫 파일에 집어 넣으시겠습니까? :) – JimR

0
 

// You should assume that Node has a Node* called next that 
// points to the next item in a list 
// Returns the head of the reversed list if successful, else NULL/0 
Node *reverse(Node *head) 
{ 
    Node *prev = NULL; 

    while(head != NULL) 
    { 
     // Save next since we will destroy it 
     Node *next = head->next; 

     // next and previous are now reversed 
     head->next = prev; 

     // Advance through the list 
     prev = head; 
     head = next; 
    } 
    return previous; 
} 
관련 문제