ListNode* reverse(ListNode* head)
{
     ListNode* p, *q, *r;
     p=head;
     q=NULL;
     while(p!=NULL)
    {
        r=q;
        q=p;
        p=p->link;
        q->link=r;
    }
    return q;
}


사용자 삽입 이미지


위에껀 내가 95퍼센트 이해한 거


ListNode* reverse(ListNode* head)
{
     ListNode* p, *c, *n;
     p=head;
     c=NULL;
     while(p!=NULL)
    {
        n=c;
        c=p;
        p=p->link;
        c->link=n;
    }
    return c;
}


여기까지가 본인이 작성함..





아래내용은 내가 더 잘 이해하기위해 다른 블로그 글을 추가함


-----------------------------------------------------------------------------------



출처 : 네이버 oasess님




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

(이미지는 Paran계정에 올려두었는데, 사이즈가 안맞아 잘려 보이네요. 클릭해서 원본 사이즈로 보시기 바랍니다.)




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

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

 

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




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

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

 

(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값으로 초기화하는 코드가 필요하게 됩니다.

 

 

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

 


블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,

void romove_node(ListNode** phead, ListNode* p, ListNode* removed)
{
 if(p==NULL)
  *phead=(*phead)->link;
 else
  p->link = removed->link;
 free(removed);
}


블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,
void insert_node(ListNode** phead , ListNode* p , ListNode* new_node)
{
 if(*phead == NULL)
 {
  new_node->link = NULL;
  *phead = new_node;
 }
 else if ( p == NULL)
 {
  new_node->link = *phead;
  *phead = new_node;
 }
 else
 {
  new_node->link = p->link;
  p->link = new_node;
 }
}
블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,

#include <stdio.h>
#include <stdlib.h>

#define MAX_LIST_SIZE 100

typedef int element;

typedef struct {
 int list[MAX_LIST_SIZE];
 int length;
}ArrayListType;

//오류처리 함수
void error(char* message)
{
 fprintf(stderr,"%s\n",message);
  exit(1);
}
//리스트 초기화
void init(ArrayListType* L)
{
 L->length=0;//(*L).length=0;
}

//리스트가 비어있으면 1을반환
//그렇지 않으면 0을 반환
int is_empty(ArrayListType* L)
{
 return L->length=0;
}

//리스트가 가득 차있으면 1을 반환
//그렇지 않으면 0을 반환
int is_full(ArrayListType* L)
{
 return L->length == MAX_LIST_SIZE;
}

//리스트 출력
void display(ArrayListType* L)
{
 int i;
 for(i=0;i<L->length ; i++)
  printf("%d\n",L->list[i]);
}
//position 삽입하고자 하는 위치
//item 삽입하고자하는자료
void add(ArrayListType* L,int position,element item)
{
 if(!is_full(L) && (position>=0) && (position <= L->length))
 {
  int i;
  for(i=(L->length-1) ; i>=position ; i--)
   L->list[i+1] = L->list[i];
  L->list[position] = item;
  L->length++;
 }
}

//position 삭제하고자 하는 위치
//반환값 삭제되는 자료
element delete(ArrayListType* L, int position)
{
 int i;
 element item;

 if(position <0 || position >= L->length)
  error("오류");
 item=L->list[position];
 for(i=position ; i<(L->length-1) ; i++)
  L->list[i]=L->list[i+1];
 L->length--;
 return item;
}


main()
{
 ArrayListType list1;
 ArrayListType* plist;

 init(&list1);
 add(&list1,0,10);
 add(&list1,0,20);
 add(&list1,0,30);
 display(&list1);

 //메모리동적할당
 plist = (ArrayListType*)malloc(sizeof(ArrayListType));
 init(plist);
 add(plist,0,10);
 add(plist,0,20);
 add(plist,0,30);
 display(plist);
 free(plist);
}


 

블로그 이미지

百見 이 不如一打 요 , 百打 가 不如一作 이다.

,