예전에 지식인 답변으로 올려두었던 것인데, 파란 사이트가 폐쇄됨에 따라 답변 내용에 포함된 그림 파일이 다 날아가버렸다. 간혹 원문을 요청하시는 분이 있어서 이곳에 올려둔다. (지식인은 답변 완료된 게시물에 대해서는 수정이 불가하다. 그래서 불가피하게 이곳에 수정본을 올린다.)


< 지식인 질문 내용 >

기본적인 링크드 리스트를 다 이해했는데 역순만 이해를 잘 못하겟네요

삽입 삭제 등등..이런것은 매우 쉬운데 역순의 알고리즘이

왜 이렇게 되는지 모르겠습니다. 

그냥 쏘스를 설명해달라는것이 아닙니다.

알고리즘에 대한 이해를 하고 싶습니다.

 

최대한 자세히 적어주시길 부탁 드릴께요.

제가 글을 읽어서 이해할수 있게 도와주시면 내공 드리겠습니다.

 

참고로 쏘스 올려봅니다.

 

ListNode *reverse(ListNode *head)

{

        ListNode *p, *c, *n;

        p = head;

        n = null;

 

       while ( p != NULL)

       {

                n = c;

                c = p;

                p = p->link;

                c->link = n;
       }

       return c;
}

 

ps.-_-적으면서도 이해가 되질 않으니 환장하것습니더...ㅜㅜ


< 이하 지식인 답변 내용 >


아무래도 이미지로 설명을 드리는게 가장 이해가 빠를것같아, 파워포인트로 그려봤습니다. 

올리신 소스로 추정하여, Head와 Tail이 없는 단일 연결 리스트로 가정하였습니다.

 

ListNode *reverse(ListNode *head)

{

        ListNode *p, *c, *n;

        p = head;

        n = null;

....

(이하생략)

  

일단 변수초기화 부분을 실행하면 아래와 같이 되겠지요.

 


변수 p에는 Head를, n에는 null값을, c는 초기화하지 않았으므로 쓰레기주소값을 가집니다.

( 나중에 보시면 아시겠지만, 변수 c는 이곳에서 null로 초기화되어야 합니다 )

 

다음에 실질적인 while()문을 최초 실행하게 되면...

       while ( p != NULL)

       {

                (1) n = c;  

                (2) c = p;  

                (3) p = p->link; 

                (4) c->link = n; 

       }

       return c;




위와같이 변수의 값들이 변경됩니다.

그림설명을 잠깐 드리자면, 회색 화살표는 이전에 가리키던 값이고, 검은색화살표가 현재 변경된 값입니다. 코드에 적힌 숫자와 그림에 적힌 숫자를 매치하면서 살펴보시면 이해가 될 것입니다.

 

(3)번을 보시면, p = p->link 를 실행하는데, p는 현재 1번 노드를 가리키고 있고, p->link는 2번노드를 가리키므로, p = p->link 는 현재의 다음노드를 가리키라는 의미입니다.

(4)번 역시 (3)번과 일맥상통합니다. 이하 설명은 생략하고 이미지로 대신하도록 하겠습니다.

 

위의 그림이 좀 복잡하므로(화살표가 너무 어지럽죠?) 좀 정리를 해 보도록 하죠.

아래의 그림과 같습니다.

 

 

이해 되시리라 생각합니다.

다시한번 while()문을 적용해보겠습니다.

 

 

 

설명은 생략하겠습니다. 복잡한 위의 그림을 다시한번 정리해보도록 하겠습니다.

아래와 같습니다.


 

 

다시 while()문을 적용합니다.


 

 

다시 정리..^^;

 

 

슬슬 끝이 보이는군요. ^^

다시한번 while()문을 적용토록 하겠습니다.

 

 

정리 들어갑니다.

 

 

이로서 완전한 리버스(Reverse)가 적용되었습니다. while()문의 조건이 p!=null 인데, 현재 p의 값이 null 이므로 루프를 빠져나와 c(리버스가 적용된 연결리스트의 헤드값)를 리턴하면서 함수는 종료합니다.

 

위의 그림을 보시면 아시겠지만, 마지막노드의 link가 쓰레기값을 가리키면서 끝나게 되지만 이는 잘못된 것입니다. 따라서 맨 처음에 언급드린 바와 같이, 변수 c또한 null값으로 초기화하는 코드가 필요하게 됩니다.

 

 

부디 이해되셨길 바랍니다. 수고하세요.

Posted by 울랄라베베
:

카테고리

분류 전체보기 (20)
Kernel programming (13)
User porgramming (2)
Etc... (2)