🎮 주제 : 인접 리스트 기반 그래프 구현 및 동적 메모리 관리
태그 : #C++ #자료구조 #그래프 #인접리스트 #포인터배열 #메모리관리
📌 학습 요약
- 인접 리스트(Adjacency List)의 효율성 : 정점마다 연결된 정점 정보를 연결 리스트로 관리하여, 간선이 적은 희소 그래프(Sparse Graph)에서 인접 행렬보다 뛰어난 메모리 효율성을 확보함
- 포인터 배열 구조 설계 : Node** list 구조를 통해 각 정점이 개별적인 연결 리스트의 헤드(Head)를 가질 수 있도록 이중 포인터 기반의 동적 배열 설계
- 동적 리스트 확장 및 초기화 : 정점 추가 시 resize를 통한 용량 관리와, 간선 추가 시 인접 리스트 배열을 안전하게 생성하고 nullptr로 초기화하는 프로세스 정립
- 연쇄적 메모리 해제 : 소멸자에서 포인터 배열뿐만 아니라 각 정점에 매달린 모든 Node들을 순회하며 삭제하여 메모리 누수를 원천 차단하는 기법 체득
🛠 주요 코드 및 구현 상세
1. 인접 리스트의 노드 구조와 그래프 골격
template <typename T>
class Graph {
private:
struct Node {
T data;
Node* next;
Node(T data, Node* link = nullptr) : data(data), next(link) {}
};
int size; // 현재 정점 개수
int capacity; // 할당된 배열 용량
T* vertex; // 정점 데이터 저장 배열
Node** list; // 각 정점의 연결 리스트 헤드를 담는 포인터 배열
};
2. 간선 추가 및 리스트 초기화 (edge)
void edge(int i, int j) {
if (size <= 0 || i >= size || j >= size) return;
// 인접 리스트 배열이 없다면 정점 개수만큼 생성
if (list == nullptr) {
list = new Node*[size];
for (int k = 0; k < size; k++) list[k] = nullptr;
}
// 양방향 그래프: i의 리스트에 j 추가, j의 리스트에 i 추가
// 새 노드를 리스트의 가장 앞에 삽입하여 O(1) 성능 확보
list[i] = new Node(vertex[j], list[i]);
list[j] = new Node(vertex[i], list[j]);
}
3. 안전한 메모리 해제 로직 (소멸자)
~Graph() {
for (int i = 0; i < size; i++) {
Node* deleteNode = list[i];
while (deleteNode != nullptr) {
Node* nextNode = deleteNode->next; // 다음 노드 미리 저장
delete deleteNode; // 현재 노드 삭제
deleteNode = nextNode; // 다음 노드로 이동
}
}
delete[] list; // 포인터 배열 해제
delete[] vertex; // 정점 배열 해제
}
✅ 주요 문법 및 개념 정리
항목 인접 행렬 (Matrix) 인접 리스트 (List)
| 공간 복잡도 | O(V^2) | O(V + E) |
| 연결 확인 | O(1) | O(Degree(V)) |
| 탐색 효율 | 모든 정점 조사 필요 | 연결된 정점만 즉시 조사 가능 |
| 적합한 그래프 | 밀집 그래프 (Dense Graph) | 희소 그래프 (Sparse Graph) |
💡 주의 : 소멸자 내 포인터 제어
- 핵심 : delete를 호출한 직후에는 해당 객체의 멤버(next)에 접근할 수 없습니다.
- 해결 : 반드시 delete 수행 전에 nextNode = deleteNode->next를 통해 다음 목적지를 확보해야 안전하게 전체 리스트를 순회할 수 있습니다.
✨ 느낀 점
- 인접 리스트는 메모리 효율이 좋지만, 동적 할당된 Node들을 관리해야 하므로 인접 행렬보다 구현의 정밀도가 더 요구됨을 배움
- Node**와 같이 포인터를 담는 배열을 다루면서 이중 포인터와 메모리 구조에 대한 이해가 한층 깊어짐
- 소멸자에서 while문을 이용해 연결 리스트를 순차적으로 삭제하는 로직을 통해 메모리 관리의 엄격함을 다시금 실감함
- 간선을 추가할 때 리스트의 맨 앞에 새 노드를 삽입하는 방식이 push_back보다 효율적일 수 있다는 설계적 통찰을 얻음
'SBS아카데미 > 게임프로그래밍' 카테고리의 다른 글
| [C++ - TIL] 이진 탐색 트리(BST) 노드 삭제의 기초 - 리프 노드 제거 로직 (0) | 2025.08.05 |
|---|---|
| [C++ - TIL] 인접 리스트의 시각화 및 이진 탐색 트리(BST)의 안정적 삽입 설계 (0) | 2025.08.04 |
| [C++ - 정리] 자료구조 개념 · 시간 복잡도 · STL · 게임 예제 정리 (4) | 2025.08.01 |
| [C++ - TIL] 그래프 자료구조, 인접 행렬, 메모리 관리, 출력 등 (2) | 2025.07.31 |
| [C++ - TIL] 그래프 자료구조 구현 및 인접 행렬 관리 (3) | 2025.07.30 |