Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions DataStructure/그래프/그래프_윤지.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
## 📖 학습 주제

- **주제**: 그래프
- **날짜**: 2024-10-26

---

## 📌 학습 내용 요약

### ✏️ 그래프의 종류와 구현

- **그래프(graph)란 ?**
- 정점(vertex)이라 불리는 데이터를 간선(edge) 혹은 링크(link)로 연결한 형태의 자료구조
- **트리** → 사이클 형성 X, 상하 관계 O
- **그래프** → 사이클 형성 O, 상하 관계 X
- **사이클(cycle)** : 특정 정점에서 시작해 다시 되돌아오는 경로가 존재하는 경우
- 간선의 형태에 따라 그래프 종류가 다름


| **연결 그래프(connected graph)** | 임의의 두 정점 사이의 경로가 존재하는 그래프 |
| --- | --- |
| **비연결 그래프(disconnected graph)** | 어떤 정점 사이에는 경로가 존재하지 않는 그래프 |
| **방향 그래프(directed graph)** | 간선에 방향이 있는 그래프 |
| **무방향 그래프(undirected graph)** | 간선에 방향이 없는 그래프 |
| **가중치 그래프(weighted graph)** | 간선에 가중치가 부여된 그래프 |
| **서브그래프(subgraph)** | 부분 그래프, 특정 그래프의 정점과 간선의 일부분으로 이루어진 그래프 |
- 가중치 그래프에서 가중치는 **비용(cost)** 라고도 불리는데 양수, 음수 모두 가능

**그래프 구현 2가지 방법**

1. **인접 행렬 기반 그래프 표현**

→ N x N 크기의 행렬로 그래프를 표현하는 방법

- **N** : 정점의 개수
- **<행, 열>**은 <출발 정점, 도착 정점>
- **1** : 정점 연결 o, **0** : 정점 연결 x
- <1, 2>가 1이라면 첫 번째 정점에서 두 번째 정점 방향으로 그래프가 연결되었음을 의미
2. **인접 리스트 기반 그래프 표현**

→ 그래프의 특정 정점과 연결된 정점들을 연결 리스트로 표현하는 방법

- 인접 리스트 기반 그래프 표현으로 무방향 그래프를 표현하는 것은 인접 행렬을 이용한 그래프 표현과 유사
- 정점 간의 연결 관계 표현 시 양방향으로 연결한다고 생각하면 됨
- 가중치 그래프도 인접 리스트로 표현 가능

### ✏️ 깊이 우선 탐색과 너비 우선 탐색

- **깊이 우선 탐색(Depth-First-Search)**

→ 그래프에서 더 이상 방문 가능한 정점이 없을 때까지 최대한 깊이 탐색하기를 반복하는 탐색 방법

![94AA0129-256B-4C74-809E-309014CDF7DA](https://github.com/user-attachments/assets/d3246ac4-40cc-4d64-bb0d-7654fff34aa2)


[그래프]

- a → b → e → c → f → d
- 깊이 우선 탐색 시 유용하게 사용되는 자료구조는 배열과 스택
- **배열**은 특정 정점의 방문 여부를 확인하기 위해 사용

→ 미방문 정점 파악을 위해 방문한 적 있는 정점들을 배열로 관리하는 것

- **스택**은 방문 중 뒤로가기가 필요할 때 사용
- **너비 우선 탐색(BFS, B**readth**-F**irst **S**earch**)**

→ 인접한 모든 정점들을 방문하고, 방문한 정점들과 연결된 모든 정점들을 방문하고, 또 방문한 정점들과 연결된 모든 정점들을 방문하기를 반복하는 탐색 방법

- a → b → c → d → e → f
- 너비 우선 탐색 시 유용하게 사용되는 자료구조는 배열과 큐
- 배열은 특정 정점의 방문 여부 확인을 위해 사용
- 큐는 연결된 정점들을 저장하기 위해 사용

→ 특정 정점과 인접한 모든 정점을 줄 세우듯 저장하고 앞으로 어떤 정점에서 탐색할지 알기 위해 사용


### ✏️ 최단 경로 알고리즘

- **최단 경로 알고리즘이란 ?**

→ 한 정점에서 목적지 정점가지 이르는 가중치의 합이 최소가 되는 경로를 결정하는 알고리즘

- **다익스트라 알고리즘(Dijkstra’s algorithm)**

→ 간선의 가중치가 음이 아닌 수라는 가정 하에 사용 가능한 알고리즘으로 특정 점점에서 다른 모든 정점까지의 최단 거리를 구해주는 알고리즘

- 특정 정점에 이르는 거리를 저장한 데이터가 함께 사용됨

**전체적인 알고리즘 동작 과정**

1. 최단 거리 테이블 상에서 시작 정점을 제외한 정점들은 모두 충분히 큰 수로 초기화 하기
2. (시작)정점 방문하기
3. 방문한 정점과 인접한 정점들 탐색하기
4. 경로 상의 가중치 합과 최단 거리 테이블 상의 값 비교하기
5. 최단 거리 테이블 갱신 가능하다면 갱신하기
6. 방문하지 않은 정점 중 최단 거리가 가장 작은 정점 방문하기
7. 더 이상 방문할 정점이 없을 때까지 3~6 과정을 반복하고 종료하기


---

## 📈 추가 학습 필요

### 그래프 구현 방법

1. **인접 행렬**

**[장점]**

- 두 노드의 간선 정보를 확인하는것이 빠름. O(1)
- 새로운 간선을 추가하고 제거하는것이 빠름. O(1)

**[문제점]**

- 간선의 개수와 상관없이 배열의 크기는 항상 N * N 개 (N은 노드의 개수)
- 위 그래프에서 노드가 4개이기 때문에 배열의 원소 개수는 (4 x 4) = 24 개
- O(N^2) 의 메모리를 사용
- 특정한 노드에 인접한 노드를 찾기위해서 모든 노드를 순회해야 함
- 노드를 추가 하거나 제거하는데 오래 걸림 O(N^2)
- 그래프의 모든 간선의 수를 찾는데 O(N^2)

**인접 행렬**은 상대적으로 노드의 개수가 적고 간선의 수가 많을때 사용하는것이 좋음

⇒ 간선이 많은 **밀집 그래프(Dense Graph)** 에 적합

1. **인접 리스트**

**[장점]**

- 메모리 효율 좋음
- 메모리 사용량은 노드 수가 아닌 간선 수에 따라 달라짐
- 특정 노드에 직접 접근할 수 있어 인접한 노드를 찾기 쉬움
- 노드의 추가 삭제가 빠름
- 새로운 간선을 빠르게 추가 할 수 있음. O(1)
- 그래프의 모든 간선의 수를 찾는데 O(N+E)

**[문제점]**

- 두 노드의 간선 정보를 확인하는데 오래 걸림

**인접 리스트**는 노드의 개수가 많고 간선의 개수가 상대적으로 적을때 사용하는것이 좋음

⇒ 간선이 적은 **희소 그래프(Sparse Graph)** 에 적합

---

## 💡 참고 자료

- [https://hsc-tech.tistory.com/12](https://hsc-tech.tistory.com/12)
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
## 📖 학습 주제

- **주제**: 배열과 연결 리스트
- **날짜**: 2024-10-24

---

## 📌 학습 내용 요약

### ✏️ 배열

- **배열(array)이란 ?**

→ 일정한 메모리 공간을 차지하는 여러 요소들이 순차적으로 나열된 자료구조

- **인덱스(index)란 ?**

→ 0부터 시작하는 고유한 순서 번호

- 인덱스를 통해 요소에 접근 또는 수정하는 시간은 요소의 개수와 무관하게 일정 → **O(1)**
- **정적 배열과 동적 배열**
- **정적 배열(static array)** : 프로그램 실행 전 크기가 고정되어 있는 배열
- **동적 배열(dynamic array)** : 실행 과정에서 크기가 변할 수 있는 배열

### ✏️ 연결 리스트

- **연결리스트(linked list)란 ?**

→ 노드의 모음으로 구성된 자료구조

- **노드(node)란 ?**

→ 저장하고자 하는 데이터와 다음 노드의 위치 정보를 포함하는 연결 리스트의 구성 단위

| 데이터 | 다음 노드 |
| --- | --- |
- 기본적으로 모든 노드들이 한 쪽 방향으로 꼬리에 꼬리를 무는 형태로 구성되어 있음
- **헤드(head)** : 첫 번째 노드
- **꼬리(tail)** : 마지막 노드
- 연결 리스트를 구성하는 모든 노드는 반드시 메모리 내에 순차적으로 저장되어 있을 필요가 없음

→ 그렇기에 연속적으로 구성되어 있는 데이터를 **불연속적으로 저장할 때 유용**하게 사용 가능

- 특정 요소에 접근할 땐 앞에서부터 순차적으로 접근할 수 밖에 없기에

→ **O(n)**

- 중간에 요소를 추가하거나 삭제하는 연산에서는 배열에 비해 강점
- 노드의 위치만 바꿔 저장하기에 재정렬 X
- 노드 접근 시간 동일 → **O(1)**

**연결 리스트 종류**

- **싱글연결리스트(singly linked list)**
- 한 쪽 방향으로 꼬리에 꼬리를 무는 형태
- 다음 노드의 위치는 알 수 있지만 이전 노드의 위치는 알기 어려움

![850552D8-ED6A-43C1-B5CE-A95B03CC7797](https://github.com/user-attachments/assets/603d27ae-63ec-4811-bf68-12fd622f9539)

- **이중연결리스트(doubly linked list)**
- 다음 노드의 위치 정보뿐만 아닌 이전 노드의 위치 정보도 포함하는 형태
- **양방향 탐색** 가능
- but, 한 노드에 2개의 위치 정보를 저장해야 하므로 더 많은 저장공간 필요

![756AE1B8-AC6A-405F-AF51-C91D119F0F26](https://github.com/user-attachments/assets/c6e2544d-277a-4a2c-9ea6-54ae8f07dd15)


- **환형연결리스트(circular linked list)**
- 꼬리 노드가 헤드 노드를 가리켜 노드들이 원형으로 구성된 형태
- 모든 노드 데이터를 여러 차례 순회해야 할 때 유용하게 활용 가능

![91E7C193-30CF-45E5-8303-D3D9020D3F4A](https://github.com/user-attachments/assets/061613d4-4f24-494f-97a5-126456c4c59d)


---

## 📈 추가 학습 필요

- 연결 리스트와 배열을 어떤 상황에서 사용해야 효율적인지 감이 잘 오지 않음.

**배열과 연결 리스트의 차이점**

- **배열은 정적(static)인 자료구조**

→ 배열은 크기를 미리 정해놔야 함

⇒ 즉, 한번 크기를 정하면 수정이 불가하고 배열 크기 이상의 데이터를 저장할 수 없다는 단점

- But ! 데이터가 순차적으로 저장되기 때문에 인덱스를 가지게 되면서 **임의 접근(random access)**이 가능
- **연결리스트는 동적(dynamic)인 자료구조**

→ 연결리스트는 크기를 미리 정할 필요가 없음

- 데이터들이 배열처럼 연속적으로 메모리에 저장되어 있지 않고 서로 떨어져 있어도 선형구조로 데이터를 저장할 수 있다는 장점

→ 크기 제한 없음 ⇒ 데이터 **추가, 삭제 자유**

- but,,, **임의 접근** 불가.
- 연결리스트가 데이터를 탐색하는 방식은 **순차 접근(sequential access)** 방식 사용

**배열과 연결 리스트의 시간 복잡도 차이**

1. **데이터 탐색**
- **배열**
- 임의 접근 방식 → 처음부터 찾기 X
- 인덱스를 통한 빠른 탐색

**⇒ 시간복잡도 : O(1)**

- **연결 리스트**
- 순차 접근 방식 → 처음부터 찾기 O

**⇒ 시간복잡도 : O(n)**

2. **데이터 추가**
- **배열**
- 데이터가 순차적으로 저장되어 있으므로 처음 위치나 그 이후에 추가될 경우 뒤에 데이터들을 한 칸씩 미뤄야 함
- 시간복잡도는 O(1)
1. 추가하려는 데이터가 **맨 뒤가 아니라면**, 추가되는 데이터 위치 이후에 있는 모든 데이터들을 한 칸씩 미뤄야 하므로 → **O(n)**
2. 추가하려는 데이터의 위치가 **맨 뒤이고, 배열에 공간이 남아있다면 →** **O(1)**
- **연결 리스트**
- 노드가 가진 메모리주소 값만 갈아 끼우면 되기에 데이터를 추가하는 행위 자체의 시간복잡도는 **O(1)**
- but, 처음 위치가 아니라면 순차적 탐색을 해야하므로 O(n) 즉,
1. 추가하려는 데이터의 **위치가 맨 앞이라면 → O(1)**
2. 추가하려는 데이터의 **위치가 맨 앞 그 이후라면** → **O(n)**
3. **데이터 삭제**
- 데이터 추가의 경우와 **동일**.

⇒ 즉, **결론**은 ???!!!

**데이터의 접근, 탐색이 중요하다면 배열을 쓰자.**

**데이터의 추가, 삭제가 중요하다면 연결리스트를 쓰자.**

---

## 💡 참고 자료

- [https://m.blog.naver.com/raylee00/221944085465](https://m.blog.naver.com/raylee00/221944085465)
95 changes: 95 additions & 0 deletions DataStructure/스택과 큐/스택과 큐_윤지.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
## 📖 학습 주제

- **주제**: 스택과 큐
- **날짜**: 2024-10-25

---

## 📌 학습 내용 요약

### ✏️ 스택

- **스택(stack)이란 ?**

→ 한 쪽에서만 데이터의 삽입 및 삭제가 가능한 자료구조

- **후입선출(L**ast **I**n **F**irst **O**ut**)**
- **푸시(push)**
- 스택에 데이터를 저장하는 연산
- **팝(pop)**
- 스택에 데이터를 빼내는 연산
- 스택이 유용한 상황
- **최근에 임시 저장한 데이터를 가장 먼저** 활용해야 할 때
- **뒤로가기** 기능을 만들고 싶을 때

### ✏️ 큐

- **큐(queue)란 ?**

→ 한 쪽으로 데이터를 삽입하고 다른 한 쪽으로 데이터를 삭제할 수 있는 자료구조

- **선입선출(F**irst **I**n **F**irst **O**ut**)**
- **인큐(enqueue)**
- 큐의 한 쪽 끝에 데이터를 삽입하는 연산
- **디큐(dequeue)**
- 큐의 한 쪽 끝에 데이터를 빼내는 연산
- 임시 저장된 데이터를 차례차례 내보내거나 꺼내 와야 하는 각종 버퍼로도 활용됨
- **원형 큐(circular queue)**
- 데이터를 삽입하는 쪽과 삭제하는 쪽 양쪽을 하나로 연결해 원형으로 사용하는 큐
- **덱(deque)**
- 양방향 큐의 약자로 양쪽으로 데이터를 삽입/삭제할 수 있는 큐
- **우선순위 큐(priority queue)**
- 저장된 요소들이 선입선출로 처리되는 것이 아닌 정해진 우선순위가 높은 순으로 처리되는 큐
- **힙(heap)** 자료구조 기반

---

## 📈 추가 학습 필요

- 스택, 큐, 덱은 언제 사용하는 건지 감이 잘 안 옴.

### 사용 예

**스택(stack)**

- **재귀 알고리즘**에서 유용하게 사용
- 역추적을 해야할 때 (ex. 문서 작업 시 실행 취소)
- 중간 원소를 삽입/삭제/탐색하지 않을 때

**큐(queue)**

- 데이터를 입력된 순서대로 처리해야 할 때
- **BFS (너비 우선 탐색)** 구현할 때

**덱(deque)**

- 앞과 뒤에서 삽입, 삭제가 자주 일어나는 경우
- 데이터의 개수가 가변적일 경우
- 데이터 검색을 거의 하지 않을 경우 (랜덤 요소에 접근해야할 때)

### 시간 복잡도

**스택(stack)**

- 원소를 **삽입/삭제**하는 경우 : **O(1)**
- **탐색**
- 탐색은 스택 구조와 맞지 않음
- 굳이 한다면 **O(n)**
- top 원소 탐색 : **O(1)**

**큐(queue)**

- 원소를 **삽입/삭제**하는 경우 : **O(1)**
- **탐색**은 큐 구조와 맞지 않음
- 굳이 한다면 **O(n)**

**덱(deque)**

- 원소를 **삽입/삭제**하는 경우 (앞/뒤에) : **O(1)**
- **탐색** : **O(1)** (index 접근)

---

## 💡 참고 자료

- [https://choiiis.github.io/data-structure/basics-of-stack-queue-and-deque/](https://choiiis.github.io/data-structure/basics-of-stack-queue-and-deque/)
Loading