2014-12-03 3 views
1

을 연결 나는 연결리스트를 구축하고이 두 구조체가 있습니다 버블이 종류의 목록

struct Element { 
    int value; 
    struct Element *next; 
}; 

struct List { 
    struct Element *first; 
}; 

가 지금은 버블 정렬과 링크 된 목록을 정렬하고 싶습니다. 현재 요소의 값과 다음 요소의 값을 비교하는 sortList 메소드를 구현했습니다. 다음 요소의 값이 현재 요소보다 크면 교체해야합니다. 그러나이 순간에는 제대로 작동하지 않습니다.

void sortList(List *list) { 
    Element *current = malloc(sizeof(Element)); 
    current = list->first; 
    Element *nextElement = malloc(sizeof(Element)); 
    nextElement = current->next; 
    Element *tmp = malloc(sizeof(Element)); 
    tmp = NULL; 

    int changed = 1; 
    while (changed) { 
     changed = 0; 
     for (current; (current != NULL) && (nextElement != NULL);) { 
      if (current->value > nextElement->value) { 
       tmp = current->next; 
       current->next = nextElement->next; 
       nextElement->next = tmp; 
       changed = 1; 
      } 
      current = current->next; 
      nextElement = nextElement->next; 
     } 
    } 
} 
+1

정확히 작동하지 않는 항목은 무엇입니까? 기본 접근법은 유효합니다; 그러나 스왑 작업을 별도의 함수로 옮기는 것이 좋습니다. – Codor

+0

목록이 올바르게 정렬되지 않았습니다. 입력 : 1 4 3 2 6 출력 : 1 4 2 6 3 – torhoehn

+0

두 개의 요소가 잘못된 순서로 목록을 정렬 할 수 있습니까? – Codor

답변

0

for, while을 다시 시작하기 전에 목록의 시작 부분을 가리키는 current 및 nextElement를 설정해야합니다! 또는 그들은 변화하지 않으며 for의 테스트 조건은 즉시 실패합니다. 또한 mallocs의 요점은 무엇입니까? 당신은 현재 노드, 다음 노드, 임시 노드만을 노드에 대한 포인터로 사용합니다. 실제 노드가 아니라 모든 노드를 삭제할 수 있다고 생각합니다. 그리고 for 문을 다시 작성하면 더 읽기 쉽습니다. 영어로 죄송합니다.

편집 : 질문 아래에 적어두면 목록 내부의 포인터를 변경해야합니다. 가장 쉬운 방법은 목록의 시작 부분에있는 하위 요소를 immediatly로 이동하고이 요소를 가리 키도록 목록의 헤드를 변경하는 것입니다. 그런 다음 나머지 목록을 정렬합니다.

+0

지금 나는 당신이 말한 것을 첫 단락에서 바꾸었다. 이제 함수는 다음과 같습니다. http://pastie.org/9758554 EDIT 파트의 모든 것을 이해하지 못합니다. 코드를 바꿀 수 있습니까? – torhoehn

+0

ok 코드를 변경합니다. 요점은 REAL 첫 번째 값을 가리 키도록 list-> first 값을 업데이트하는 것입니다. 5 2 목록 예제에서이 작업을 수행하지 않는 문제를 볼 수 있습니다. 목록이 정렬되어 2 5 BUT list-> 5가되므로 5가 사라집니다. – GiuMaz

+0

링크 http://pastie.org/9760695 – GiuMaz

0

프로그램이 기존 목록을 정렬한다고 가정하면 sortList에 노드를 할당 할 이유가 없습니다. 기존 노드에 대한 포인터를 조작해야합니다.

노드를 교체 할 때 현재 노드를 가리키는 포인터를 업데이트해야합니다 (list.first 또는 Element.next). 포인터에 포인터를 사용하면 조금 더 쉬워집니다.

struct Element **ppcur; /* pointer to list->first or element->next */ 
/* ... */ 
    if(list == NULL || list->first == NULL) 
     return NULL; 
    for(ppcur = &(list->first); pnxt = (pcur = *ppcur)->next; 
     ppcur = &((*ppcur)->next)){ 
    /* ... */