Skip to content

Commit 67b5469

Browse files
add array & linked list
1 parent 3393a79 commit 67b5469

File tree

2 files changed

+271
-0
lines changed

2 files changed

+271
-0
lines changed

data_structure/data_structure.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
11
## Array & Linked List
2+
<details>
3+
<summary>[핵심 답변]</summary>
4+
<div markdown="1">
5+
Array는 연관된 data를 <b>메모리상에 연속적이며 순차적</b>으로 <b>미리 할당된 크기</b>만큼 저장하는 자료구조 입니다.
6+
</div>
7+
</details>

data_structure/data_structure_sg.md

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# Array & Linked List
2+
3+
## Q. Array는 어떤 자료구조 인가요?
4+
<details>
5+
<summary>[핵심 답변]</summary>
6+
<div markdown="1">
7+
8+
Array는 연관된 data를 <b>메모리상에 연속적이며 순차적</b>으로 <b>미리 할당된 크기</b>만큼 저장하는 자료구조 입니다.
9+
</div>
10+
</details>
11+
12+
<details>
13+
<summary>[면접 🍯 TIP]</summary>
14+
<div markdown="1">
15+
16+
> 💡 Array에 관한 질문을 할 때에는 매우 높은 확률로 Linked List에 대한 질문도 나오게 됩니다. 따라서 Array의 다양한 특징 중에서 Linked List와 비교가 되는 특성들을 위주로 대답을 하게 되면 편하게 풀어나갈 수 있습니다!
17+
18+
Array와 Linked List의 가장 큰 차이점은 메모리에 저장되는 방식과 이에 따른 operation의 연산 속도(time complexity) 입니다. 이를 유념해서 공부해 가시면 좋은 답변을 하실 수 있습니다.
19+
20+
## Array의 특징
21+
22+
- 고정된 저장 공간(fixed-size)
23+
- 순차적인 데이터 저장(order)
24+
25+
Array의 장점은 lookup과 append가 빠르다는 것입니다. 따라서 조회를 자주 해야되는 작업에서는 Array 자료구조를 많이 씁니다.
26+
27+
Array의 단점은 fixed-size 특성상 선언시에 Array의 크기를 미리 정해야 된다는 것입니다. 이는 메모리 낭비나 추가적인 overhead가 발생할 수 있습니다.
28+
29+
## 시간복잡도
30+
||Array|
31+
|------|---|
32+
|access|$O(1)$|
33+
|append|$O(1)$|
34+
|마지막 원소delete|$O(1)$|
35+
|insertion|$O(n)$|
36+
|deletion|$O(n)$|
37+
|search|$O(n)$|
38+
39+
</div>
40+
</details>
41+
42+
<details>
43+
<summary>[꼬꼬무 문답]</summary>
44+
<div markdown="1">
45+
<details>
46+
<summary>
47+
Q) 미리 예상한 것보다 더 많은 수의 data를 저장하느라 Array의 size를 넘어서게 됐습니다. 이 때, 어떻게 해결할 수 있을까요?
48+
</summary>
49+
<div markdown="1">
50+
<b>[핵심 답변]</b>
51+
52+
기존의 size보다 더 큰 Array를 선언하여 데이터를 옮겨 할당합니다. 모든 데이터를 옮겼다면 기존 Array는 메모리에서 삭제하면 됩니다. 이런식으로 동적으로 배열의 크기를 조절하는 자료구조를 Dynamic array라고 합니다.
53+
54+
또 다른 방법으로는, size를 예측하기 쉽지 않다면 Array대신 Linked list를 사용함으로써 데이터가 추가될 때마다 메모리공간을 할당받는 방식을 사용하면 됩니다.
55+
</div>
56+
</details>
57+
58+
</div>
59+
</details>
60+
61+
---
62+
63+
64+
## Q. Dynamic Array는 어떤 자료구조 인가요?
65+
<details>
66+
<summary>[핵심 답변]</summary>
67+
<div markdown="1">
68+
69+
Array의 경우 size가 고정되었기 때문에 선언시에 설정한 size보다 많은 갯수의 data가 추가되면 저장할 수 없습니다. 이에 반해 Dynamic Array는 저장공간이 가득 차게 되면 resize를 하여 유동적으로 size를 조절하여 데이터를 저장하는 자료구조 입니다.
70+
</div>
71+
</details>
72+
73+
<details>
74+
<summary>[면접 🍯 TIP]</summary>
75+
<div markdown="1">
76+
77+
> Array의 특징중에 fixed-size의 한계점을 보완하고자 고안된 자료구조인 Dynamic Array에 대해서 면접을 위해 깊게 공부하실 내용은 크게 두 가지 입니다.
78+
> 1. resize를 하는 방식
79+
> 2. 데이터 추가(append)할 때의 시간복잡도
80+
81+
Dynamic Array는 size를 자동적으로 resizing을 하는 Array입니다. 기존에 고정된 size를 가진 Static Array의 한계점을 보안하고자 고안되었습니다. Dynamic Array는 data를 계속 추가하다가 기존에 할당된 memory를 초과하게 되면, size를 늘린 배열을 선언하고 그곳으로 모든 데이터를 옮김으로써 늘어난 크기의 size를 가진 배열이 됩니다. 이를 resize라고 합니다. 이로써 새로운 data를 저장할 수 있게 됩니다. 따라서 Dynamic Array는 size를 미리 고민할 필요가 없다는 장점이 있습니다.
82+
83+
resizing 을 하는 방법은 여러 가지가 있는데, 대표적으로 기존 Array size의 2배 size를 할당하는 doubling이 있습니다.
84+
85+
## Doubling
86+
87+
resize의 대표적인 방법으로는 Doubling이 있습니다. 데이터를 추가(append $O(1)$) 하다가 메모리를 초과하게 되면 기존 배열의size보다 두배 큰 배열을 선언하고 데이터를 일일이 옮기는(n개의 데이터를 일일이 옮겨야 하므로 $O(n)$ ) 방법입니다.
88+
89+
## 분할상환 시간복잡도 Amortized time complexity
90+
91+
Dynamic array에 데이터를 추가할 때마다 $O(1)$의 시간이 걸리게 됩니다. → 추가를 하다가 미리 선언된 size를 넘어서는 순간에 resize를 하게 됩니다. → 이 때는 일일이 데이터를 모두 옮겨야 되기 때문에 이 때만큼은$O(n)$의 시간이 걸리게 됩니다.
92+
93+
그렇다면 결과적으로 append의 시간복잡도는 $O(1)$일까요 아니면 $O(n)$일까요?
94+
95+
append의 총 과정을 살펴보면 데이터를 마지막 인덱스에 추가하는($O(1)$)작업이 대다수이고, size를 넘어설 때는 size를 두 배 늘리고 데이터를 일일이 옮기는 과정 (resize $O(n)$)이 아주 가끔 발생합니다. 결론부터 말하자면 append의 전체적인 시간복잡도는 $O(1)$입니다. 좀 더 정확히 말하면 <b>amortized</b> $O(1)$이라고 부릅니다.
96+
97+
쉽게 설명하자면 가끔 발생하는 O(n)의 resize하는 시간을, 자주 발생하는 O(1)의 작업들이 분담해서 나눠 가짐으로써 전체적으로 O(1)의 시간이 걸린다고 생각하시면 됩니다.
98+
</div>
99+
</details>
100+
101+
<details>
102+
<summary>[꼬꼬무 문답]</summary>
103+
<div markdown="1">
104+
&nbsp;&nbsp; Q) Dynamic Array를 Linked list와 비교하여 장단점을 설명해 주세요.
105+
106+
<br/>
107+
<b>[핵심 답변]</b>
108+
109+
Linked List와 비교했을 때, Dynamic Array의 장점은
110+
111+
- 데이터 접근과 할당이 $O(1)$로 굉장히 빠릅니다. 이는 index 접근하는 방법이 산술적인 연산 [배열 첫 data의 주소값] + [offset]으로 이루어져 있기 때문입니다. (randam access)
112+
- Dynamic Array의 맨 뒤에 데이터를 추가하거나 삭제하는 것이 상대적으로 빠릅니다.($O(1)$)
113+
114+
Linked List와 비교했을 때, Dynamic Array의 단점은
115+
116+
- Dynamic Array의 맨 끝이 아닌 곳에 data를 insert or remove할 때, 느린 편입니다($O(n)$). 느린 이유는 메모리상에서 연속적으로 데이터들이 저장되어 있기 때문에, 데이터를 추가 삭제할 때 뒤에 있는 data들을 모두 한칸씩 shift 해야되기 때문입니다.
117+
- resize를 해야할 때, 예상치 못하게 현저히 낮은 performance가 발생합니다.
118+
- resize에 시간이 많이 걸리므로 필요한 것 이상 memory공간을 할당받습니다. 따라서 사용하지 않고 있는 낭비되는 메모리공간이 발생합니다.
119+
</div>
120+
</details>
121+
122+
---
123+
## Q. Array는 어떤 자료구조 인가요?
124+
125+
<details>
126+
<summary>[핵심 답변]</summary>
127+
<div markdown="1">
128+
129+
Linked List는 Node라는 구조체로 이루어져 있는데, Node는 데이터 값과 다음 Node의 address를 저장합니다. Linked List는 물리적인 메모리상에서는 비연속적으로 저장이 되지만 Linked list를 구성하는
130+
각각의 Node가 next Node의 address를 가리킴으로써 논리적인 연속성을 가진 자료구조입니다.
131+
132+
</div>
133+
</details>
134+
135+
<details>
136+
<summary>[면접 🍯 TIP]</summary>
137+
<div markdown="1">
138+
139+
Linked List는 Node라는 구조체로 이루어져 있는데, Node는 데이터 값과 다음 Node의 address를 저장합니다. Linked List는 물리적인 메모리상에서는 비연속적으로 저장이 되지만 Linked list를 구성하는 각각의 Node가 next Node의 address를 가리킴으로써 논리적인 연속성을 가진 자료구조입니다.
140+
141+
> 💡 Linked List는 tree, graph등 다른 자료구조를 구현할 때 자주 쓰이는 기본 자료구조 입니다. 면접에서 Linked list를 설명할 때에는 메모리상에서 불연속적으로 데이터가 저장되는 점과 Node의 next address를 통해 불연속적인 데이터를 연결하여 논리적 연속성을 보장한다는 점을 중심으로 설명하면 됩니다.
142+
> 또한, 데이터가 추가 되는 시점에서 메모리를 할당하기 때문에 메모리를 좀 더 효율적으로 사용할 수 있다는 장점도 답변으로 구성하면 좋습니다.
143+
144+
145+
### 논리적 연속성
146+
147+
148+
각 Node들은 next address정보를 가지고 있기 때문에 논리적으로 연속성을 유지하면서 연결되어 있습니다. Array의 경우 연속성을 유지하기 위해 물리적 메모리 상에서 순차적으로 저장하는 방법을 사용하였고, Linked list에는 메모리에서 연속성을 유지하지 않아도 되기 때문에 메모리 사용이 좀 더 자유로운 대신, Next address를 추가적으로 저장해야 하기 때문에 데이터 하나당 차지하는 메모리가 더 커지게 됩니다.
149+
150+
(1) 그림에서 링크드리스트가 연속적으로 저장된것처럼 보이지만 실제 메모리상에서는 (2)와 같다
151+
152+
(1) 논리적 연속성
153+
154+
<img src="https://user-images.githubusercontent.com/32692807/231956326-c478a93b-c01c-4e0b-b1ca-f6c70585fd2f.jpeg" height="400" width="600">
155+
156+
(2) 물리적 불연속성
157+
158+
<img width="464" alt="스크린샷 2022-08-03 오후 4 46 09" src="https://user-images.githubusercontent.com/32692807/231959611-9a8ad5e4-4dc8-4f0a-bc06-df36e19518a5.png">
159+
160+
## 시간복잡도
161+
162+
Array의 경우 중간에 데이터를 삽입/삭제하게 되면 해당 인덱스의 뒤에 있는 모든 원소들은 shift를 해야만 했습니다. 그러다 보니 $O(n)$의 시간복잡도를 갖게 되었습니다. 하지만 Linked list를 물리적으로 옮길 필요없이 next address가 가리키는 주소값만 변경하면 되기 때문에 $O(1)$의 시간복잡도로 삽입/삭제가 가능합니다.
163+
164+
||Linked list|
165+
|------|---|
166+
|access|$O(n)$|
167+
|search|$O(n)$|
168+
|insertion|$O(1)$|
169+
|deletion|$O(1)$|
170+
171+
<img width="464" alt="스크린샷 2022-08-03 오후 4 46 09" src="https://user-images.githubusercontent.com/32692807/231966878-08fb1bde-48b7-4e7b-bd69-899207845cbd.jpeg">
172+
<img width="464" alt="스크린샷 2022-08-03 오후 4 46 09" src="https://user-images.githubusercontent.com/32692807/231967005-dd12ff03-db62-4632-88a0-0f8616823ec8.jpeg">
173+
174+
175+
</div>
176+
</details>
177+
178+
---
179+
180+
## Q. ⭐ Array vs Linked list를 비교해서 설명해주세요
181+
182+
<details>
183+
<summary>[핵심 답변]</summary>
184+
<div markdown="1">
185+
186+
Array는 메모리 상에서 연속적으로 데이터를 저장하는 자료구조 입니다. Linked List는 메모리상에서는 연속적이지 않지만, 각각의 원소가 다음 원소의 메모리 주소값을 저장해 놓음으로써 논리적 연속성을 유지합니다.
187+
188+
그래서 각 operation의 시간복잡도가 다릅니다. 데이터 조회는 Array의 경우 $O(1)$, Linked list는 $O(n)$의 시간복잡도를 갖습니다. 삽입/삭제는 Array $O(n)$, Linked list $O(1)$의 시간복잡도를 갖습니다.
189+
190+
따라서 얼마만큼의 데이터를 저장할지 미리 알고있고, 조회를 많이 한다면 Array를 사용하는 것이 좋습니다. 반면에 몇개의 데이터를 저장할 지 불확실하고 삽입 삭제가 잦다면 Linked list를 사용하는 것이 유리합니다.
191+
</div>
192+
</details>
193+
194+
195+
<details>
196+
<summary>[면접 🍯 TIP]</summary>
197+
<div markdown="1">
198+
199+
> Array와 Linked List의 주된 차이점들은 메모리 구조에 기인합니다. Array는 메모리상에서 연속적으로 데이터를 저장하고, Linked List는 불연속적으로 저장합니다. 메모리 구조의 차이로 인해 operation구현방법이 다르고 시간복잡도도 다릅니다. 또한 메모리 활용도에서도 차이가 있습니다. 상황에 따라 메모리를 효율적으로 사용할 수 있는 자료구조가 달라집니다. 이를 유념해서 학습을 해봅시다!
200+
201+
Array는 메모리 상에서 연속적으로 데이터를 저장하는 자료구조 입니다. Linked List는 메모리상에서는 연속적이지 않지만, 각각의 원소가 다음 원소의 메모리 주소값을 저장해 놓음으로써 논리적 연속성을 유지합니다.
202+
203+
그래서 각 operation의 시간복잡도가 다릅니다. 데이터 조회는 Array의 경우 $O(1)$, Linked list는 $O(n)$의 시간복잡도를 갖습니다. 삽입/삭제는 Array $O(n)$, Linked list $O(1)$의 시간복잡도를 갖습니다.
204+
205+
따라서 얼마만큼의 데이터를 저장할지 미리 알고있고, 조회를 많이 한다면 Array를 사용하는 것이 좋습니다. 반면에 몇개의 데이터를 저장할 지 불확실하고 삽입 삭제가 잦다면 Linked list를 사용하는 것이 유리합니다.
206+
207+
### 조회 (lookup)
208+
209+
Array는 메모리상에서 연속적으로 데이터를 저장하였기 때문에 저장된 데이터에 즉시 접근(random access $O(1)$)할 수 있습니다. 이와 반면 Linked List는 메모리 상에서 불연속적으로 데이터를 저장하기 때문에 순차 접근(Sequential Access)만 가능합니다. 즉, 특정 index의 데이터를 조회하기 위해 $O(n)$의 시간이 걸리게 됩니다.
210+
211+
### 삽입/삭제 (insert/delete)
212+
213+
Array의 경우 맨 마지막 원소를 추가/삭제하면 시간복잡도가 $O(1)$입니다. 하지만 맨 마지막 원소가 아닌 중간에 있는 원소를 삽입/삭제하면 해당 원소보다 큰 인덱스의 원소들을 한 칸씩 shift 해줘야 하는 비용(cost)이 발생합니다. 따라서 이 경우에는 시간복잡도가 $O(n)$이 됩니다.
214+
215+
Linked List는 어느 원소를 추가/삭제 하더라도 node에서 다음주소를 가르키는 부분만 다른 주소 값으로 변경하면 되기 때문에 shift할 필요 없어 시간복잡도가 $O(1)$입니다.
216+
217+
하지만 Linked list의 경우 추가/삭제를 하려는 index까지 도달하는데 $O(n)$의 시간이 걸리기 때문에, 실질적으로 Linked List도 추가/삭제 시에 $O(n)$의 시간이 걸린다고 볼 수 있습니다.
218+
219+
### memory
220+
221+
Array의 주된 장점은 데이터 접근과 append가 빠르다는 것입니다. 하지만 메모리 낭비라는 단점이 있습니다. 배열은 선언시에 fixed size를 설정하여 메모리 할당을 합니다. 즉, 데이터가 저장되어 있지 않더라도 메모리를 차지하고 있기 때문에 메모리 낭비가 발생합니다.
222+
223+
이와 반면 Linked List는 runtime중에서도 size를 늘리고 줄일 수 있습니다. 그래서 initial size를 고민할 필요 없고, 필요한 만큼 memorry allocation을 하여 메모리 낭비가 없습니다.
224+
</div>
225+
</details>
226+
<details>
227+
<summary>[꼬꼬무 문답]</summary>
228+
<div markdown="1">
229+
&nbsp;&nbsp;
230+
<details>
231+
<summary> Q. 어느 상황에 Linked list를 쓰는게 Array보다 더 나을까요?</summary>
232+
<div markdown="1">
233+
<b>[핵심 답변]</b>
234+
235+
- $O(1)$으로 삽입/삭제를 자주 해야 될 때
236+
- 얼마만큼의 데이터가 들어올지 예측을 할 수 없을 때
237+
- 조회 작업을 별로 하지 않을 때
238+
</div>
239+
</details>
240+
<details>
241+
<summary>Q. 어느 상황에 Array를 쓰는게 Linked list보다 더 나을까요?</summary>
242+
<div markdown="1">
243+
<b>[핵심 답변]</b>
244+
245+
- 조회 작업을 자주 해야될 때
246+
- Array를 선언할 당시에 데이터의 갯수를 미리 알고 있을때
247+
- 데이터를 반복문을 통해서 빠르게 순회할 때.
248+
- 메모리를 적게 쓰는게 중요한 상황일 때. Linked list보단 Array가 메모리를 적게 차지 하기 때문에 미리 들어올 데이터의 양을 알고만 있다면 Array가 메모리를 더 효율적으로 사용합니다.
249+
</div>
250+
</details>
251+
<details>
252+
253+
<summary>Q. Array와 Linked List의 memory allocation은 언제 일어나며, 메모리의 어느 영역을 할당 받나요?</summary>
254+
255+
<div markdown="1">
256+
<b>[핵심 답변]</b>
257+
258+
Array는 compile 단계에서 memory allocation이 일어납니다. 이를 Static Memory Allocation이라고 합니다. 이 경우 Stack memory영역에 할당됩니다.
259+
260+
Linked List의 경우 runtime 단계에서 새로운 node가 추가될 때마다 memory allocation이 일어납니다. 이를 Dynamic Memory Allocation이라고 부릅니다. Heap메모리 영역에 할당됩니다.
261+
<img src="https://user-images.githubusercontent.com/32692807/231968193-8892e9c4-6958-4165-92e7-fac02bcb9736.jpeg">
262+
</div>
263+
</details>
264+
</div>
265+
</details>

0 commit comments

Comments
 (0)