C언어 연결 리스트 뒤집기 (Reverse Linked List)

코딩C언어
읽는데 7분 소요
처음 쓰여진 날: 2026-05-06
마지막 수정일: 2026-05-06
조회수:

요약

C언어 연결 리스트의 순서를 거꾸로 뒤집는 in-place 알고리즘을 단계별로 알아봅니다. prev/curr/next 3포인터로 화살표 방향만 바꿔 같은 메모리에서 리스트를 반전시키는 과정을 다이어그램과 함께 추적합니다.

핵심 정리

개념설명
in-place 뒤집기새 노드 없이 기존 노드의 next 값만 덮어써 방향만 반전
prev이미 뒤집힌 부분의 첫 노드 (시작 시 NULL)
curr지금 방향을 바꿀 노드 (시작 시 원래 head)
nextcurr->next의 백업, 다음 노드 주소를 잃지 않기 위함
종료 조건curr == NULL (원래 리스트 끝까지 이동)
새 head루프 종료 시점의 prev

알고리즘 개요 심화

연결 리스트의 노드 순서를 거꾸로 바꾸는 알고리즘입니다. 새 노드를 만들지 않고 기존 노드 t1, t2, t3는 그대로 두고 각 노드 안의 next 값만 새로 덮어써서 화살표 방향을 거꾸로 바꿉니다. 값(5, 7, 11)을 서로 옮기지 않고도 화살표만 거꾸로 돌리면 결과가 같다는 점이 핵심입니다. 이를 in-place(제자리) 뒤집기라고 부릅니다.

핵심은 포인터 3개(prev, curr, next)를 한 노드씩 다음 노드로 이동시키며 curr->nextprev 방향으로 다시 연결하는 것입니다.

포인터역할
prev지금까지 뒤집어 놓은 새 리스트의 첫 노드. 시작 시점에는 뒤집힌 노드가 하나도 없으므로 NULL. 원래 첫 노드가 새 리스트의 끝이 되어야 하므로 NULL이어야 함
curr지금 방향을 바꿀 노드
nextcurr->next를 미리 저장해 두는 임시 변수. 방향을 뒤집기 전에 다음 노드의 주소를 백업해 두는 것으로, 그렇게 안 하면 curr->nextprev로 덮어쓰는 순간 원래 다음 노드 주소가 사라져서 그 노드에 더 이상 도달할 수 없습니다

연결 리스트 페이지에서 만든 t3 -> t2 -> t1 -> NULL 리스트를 뒤집어 t1 -> t2 -> t3 -> NULL로 만들어 봅시다.


코드 심화

c
코드 하이라이팅 중...

prevNULL1로 초기화합니다. while이 한 번 돌 때마다 1 ~ 4번이 차례로 실행됩니다. 그 후 다시 currNULL인지 검사해서 NULL이면 빠져나옵니다.

c
코드 하이라이팅 중...

루프가 끝났을 때 prev가 가리키고 있는 노드(&t1)가 새로운 시작점입니다. 원래 리스트의 마지막 노드 t1은 뒤집힌 리스트의 첫 노드가 됩니다. 마지막 회차에서 prev = curr = &t1이 실행된 후 루프가 끝나므로, 결과적으로 prev가 새 head를 가리키게 됩니다.


단계별 추적 심화

루프 진입 직전 상태

반복이 시작되기 전 변수와 노드의 상태입니다. prevNULL, curr은 시작 노드 &t3를 가리키고, 노드 연결은 아직 원래 방향(t3 -> t2 -> t1 -> NULL) 그대로입니다. 아래 다이어그램이 그 초기 상태입니다.

연결 리스트 뒤집기 초기 상태
prev=NULL, curr=&t3. 노드 연결은 t3 -> t2 -> t1 -> NULL 그대로.

1회차 반복

curr = &t3인 상태에서 진입합니다.

  1. next = curr->nextnext = &t2
  2. curr->next = prevt3.next = NULL (원래 t3는 리스트의 첫 노드였지만, 뒤집은 결과 리스트에서는 마지막 노드가 됩니다. 그래서 t3.next를 NULL로 바꿔줍니다.)
  3. prev = currprev = &t3
  4. curr = nextcurr = &t2

t3가 t2와 분리되고, prev가 t3로 이동합니다. 4번까지 실행한 뒤 다시 while 조건으로 돌아가 curr(=&t2)이 NULL인지 검사합니다. NULL이 아니므로 다시 1번부터 실행합니다.

연결 리스트 뒤집기 1회차 반복 후 상태
t3.next가 NULL로 바뀌어 t3가 끝 노드가 되고, prev=&t3, curr=&t2로 이동.

2회차 반복

curr = &t2인 상태에서 진입합니다.

  1. next = curr->nextnext = &t1
  2. curr->next = prevt2.next = &t3 (t2 -> t3로 방향이 뒤집힘)
  3. prev = currprev = &t2
  4. curr = nextcurr = &t1

t2가 t3 쪽으로 다시 연결되어 지금까지 뒤집힌 부분(t2 -> t3 -> NULL)이 만들어지고, 아직 안 뒤집힌 t1이 따로 남아 있습니다.

연결 리스트 뒤집기 2회차 반복 후 상태
t2.next가 &t3가 되어 t2 -> t3 -> NULL 부분 리스트 형성, prev=&t2, curr=&t1로 이동.

3회차 반복

curr = &t1인 상태에서 진입합니다.

  1. next = curr->nextnext = NULL
  2. curr->next = prevt1.next = &t2
  3. prev = currprev = &t1
  4. curr = nextcurr = NULL

마지막 노드 t1이 t2 쪽으로 연결되며 전체 리스트가 완성됩니다. 다음 반복 조건 while(curr)currNULL이므로 거짓이 되어 루프가 종료됩니다.

연결 리스트 뒤집기 3회차 반복 후 상태
t1.next=&t2로 연결 완료. prev=&t1이 새 head가 되고, curr=NULL이라 루프 종료.

최종 결과

head = prev = &t1t1 -> t2 -> t3 -> NULL (값 순서: 5, 7, 11)

뒤집힌 연결 리스트 최종 상태
루프 종료 후 head 기준으로 정리한 새 리스트. head -> t1 -> t2 -> t3 -> NULL 순서로 원본의 정반대가 됩니다.

변수 변화 추적표 심화

각 회차 4단계가 모두 끝난 직후의 변수 상태입니다. next는 매 회차 1단계에서 갱신된 후 그 회차 동안 바뀌지 않으므로, 회차 후 next 값 = 그 회차 1단계 결과입니다.

여러 부분 리스트가 동시에 존재하면 |로 구분합니다. 화살표는 모두 next 방향(가리키는 쪽)을 의미합니다.

시점prevcurrnext노드 연결 상태
진입 직전NULL&t3NULLt3 -> t2 -> t1 -> NULL
1회차 후&t3&t2&t2t3 -> NULL | t2 -> t1 -> NULL
2회차 후&t2&t1&t1t2 -> t3 -> NULL | t1 -> NULL
3회차 후&t1NULLNULLt1 -> t2 -> t3 -> NULL

자주 하는 실수 심화

next 백업을 건너뛴 경우의 끊김
next = curr->next 백업 단계를 건너뛰고 곧바로 curr->next = prev를 실행하면, t3.next가 NULL로 덮어써져 t2와 t1으로 가는 길이 영원히 사라집니다.

연습 문제


Footnotes

  1. 0(빈 주소)을 의미하는 매크로입니다. <stdio.h> 등 표준 헤더에 정의되어 있으며, prev = NULLprev = 0과 같은 뜻입니다.


관련 글

(41개)
제목태그시험
C언어 형변환 (Casting)
C언어
-
C언어 사용자 정의 함수 기초
C언어
-
C언어 sizeof 연산자
C언어
-
C언어 연결 리스트 뒤집기 (Reverse Linked List) | 정처기 감자