연결 리스트 (Linked List)의 연산
Linked List(연결 리스트)
는 배열(Array)과 같이 순차적인 데이터를 표현하는 데 적합한 자료 구조이다. 각 데이터 항목을 node(노드)
라고 부르며, 이 node
들이 포인터로 연결되어 리스트를 구성한다.
- Node(노드): 데이터와 다음
node
를 가리키는 포인터(link
또는next
)로 구성된 단위이다.item(항목)
또는element(원소)
라고도 부른다. - Head(헤드):
Linked List
의 첫 번째node
를 가리키는 포인터이다. - 장점: 프로그램 실행 중에 메모리가 허용하는 한 동적으로
node
의 수를 늘리거나 줄일 수 있다. 이는 자기 참조 구조체(self-referential structure)를 이용하여 구현된다.
Node(노드) 추가
맨 앞에 Node(노드) 추가
Linked List
의 가장 앞에 새로운 node
를 추가하는 과정은 다음과 같다.
- 새로운
node
를 위한 메모리를 동적으로 할당한다. - 할당된
node
의 데이터 필드에 새로운 값을 저장한다. - 새로운
node
의link
가 기존의head(헤드)
가 가리키던 첫 번째node
를 가리키도록 설정한다. head
포인터가 새로운node
를 가리키도록 갱신한다.
이 방식을 사용하면 리스트의 길이에 상관없이 항상 빠른 시간 안에 node
를 추가할 수 있다.
맨 뒤에 Node(노드) 추가
Linked List
의 가장 마지막에 새로운 node
를 추가하는 과정은 다음과 같다.
- 새로운
node
를 생성하고 데이터를 저장한 후,link
는NULL
로 설정한다. - 만약
Linked List
가 비어 있다면(head
가NULL
이라면),head
가 새로운node
를 가리키게 한다. - 리스트가 비어있지 않다면,
head
부터 시작하여link
가NULL
인 마지막node
를 찾을 때까지 순회한다. - 찾은 마지막
node
의link
가 새로 생성한node
를 가리키도록 설정한다.
Node(노드) 삽입
중간에 Node(노드) 삽입 (일반)
Linked List
의 중간에 새로운 node
를 삽입하는 과정은 다음과 같다.
- 삽입할 새로운
node
를 동적으로 생성하고 데이터를 저장한다. - 삽입하려는 위치의 바로 이전
node
까지 이동한다. - 새로운
node
의link
가 이전node
의link
가 가리키던node
를 가리키게 한다. - 이전
node
의link
가 새로운node
를 가리키도록 주소값을 갱신한다.
정렬된 List에 Node(노드) 삽입
데이터가 정렬된 상태를 유지하도록 Linked List
에 node
를 삽입하는 경우, 삽입 위치를 찾아야 한다. 이 과정은 주로 두 개의 포인터(p
, q
)를 사용하여 효율적으로 처리할 수 있다.
p
: 현재 비교 대상node
를 가리키는 포인터q
:p
의 바로 이전node
를 가리키는 포인터
삽입 과정:
p
와q
를head(헤드)
에서부터 이동시키며 새로운 데이터가 들어갈 위치를 탐색한다.p
의 데이터가 삽입할 데이터보다 커지는 순간이 삽입 위치이다.- 탐색이 완료되면 새로운
node
를q
와p
사이에 삽입한다.newNode->next = p;
q->next = newNode;
- 예외 처리:
- 맨 앞에 삽입: 삽입할 데이터가
head
의 데이터보다 작을 경우,head
를 새로운node
로 갱신해야 한다. - 맨 뒤에 삽입: 리스트의 끝까지 탐색한 경우(
p
가NULL
이 된 경우), 마지막node
(q
) 뒤에 새로운node
를 추가한다.
- 맨 앞에 삽입: 삽입할 데이터가
Node(노드) 삭제
Node(노드) 삭제 (일반)
Linked List
에서 특정 node
를 삭제하는 과정은 다음과 같다.
- 삭제하려는
node
의 바로 이전node
로 이동한다. - 삭제할
node
를 임시 포인터에 저장해둔다. - 이전
node
의link
가 삭제할node
의 다음node
를 가리키도록 변경하여 연결을 끊는다. - 임시 포인터를 사용하여 삭제된
node
의 메모리를 해제(free
)한다.
정렬된 List에서 Node(노드) 삭제
정렬된 Linked List
에서 node
를 삭제하는 과정은 삽입과 마찬가지로 두 개의 포인터(p
, q
)를 사용한다.
p
: 삭제할node
를 찾기 위한 포인터q
:p
의 이전node
를 가리키는 포인터
삭제 과정:
p
와q
를 이동시키며 삭제할 데이터를 가진node
(p
)를 찾는다.- 최적화: 탐색 중
p
의 데이터가 삭제할 데이터보다 커지면, 해당 데이터는 리스트에 존재하지 않는 것이므로 탐색을 즉시 중단할 수 있다. - 삭제할
node
를 찾으면,q
의link
가p
의 다음node
를 가리키도록 변경한다.q->next = p->next;
p
가 가리키는node
의 메모리를 해제한다.- 예외 처리:
- 맨 앞 Node(노드) 삭제: 삭제할
node
가head(헤드)
일 경우,head
를 다음node
로 갱신한 후 기존head
의 메모리를 해제해야 한다. - 삭제할 Node(노드)가 없는 경우: 리스트의 끝까지 탐색해도 데이터를 찾지 못하면 아무 작업도 수행하지 않는다.
- 맨 앞 Node(노드) 삭제: 삭제할