1+ #include < cassert>
2+ #include < iostream>
3+ #include < stdexcept>
4+ using namespace std ;
5+ class MinHeap {
6+ public:
7+ MinHeap ();
8+ ~MinHeap ();
9+
10+ void push (int value);
11+ void pop ();
12+
13+ int & top ();
14+
15+ int size () const ;
16+ int capacity () const ;
17+ bool empty () const ;
18+
19+ void clear ();
20+ void reserve (int newCapacity);
21+
22+ private:
23+ int * data;
24+ int current_size;
25+ int current_capacity;
26+
27+ void siftUp (int index);
28+ void siftDown (int index);
29+ };
30+ // 10:50 시작
31+ MinHeap::MinHeap (): data(nullptr ), current_size(0 ), current_capacity(0 ) {}
32+ MinHeap::~MinHeap () {
33+ clear ();
34+ delete[] data;
35+ }
36+
37+ void MinHeap::push (int value) {
38+ if (current_capacity == current_size) {
39+ reserve (current_capacity == 0 ? 1 : current_capacity * 2 );
40+ }
41+
42+ data[current_size] = value;
43+ current_size++;
44+ siftUp (current_size-1 );
45+ }
46+ void MinHeap::pop () {
47+ if (current_size == 0 ) return ;
48+
49+ data[0 ] = data[--current_size];
50+ if (current_size == 0 ) return ;
51+
52+ siftDown (0 );
53+ }
54+
55+ int & MinHeap::top () {
56+ if (current_size == 0 ) throw out_of_range (" Heap is Empty." );
57+
58+ return data[0 ];
59+ }
60+
61+ int MinHeap::size () const {
62+ return current_size;
63+ }
64+ int MinHeap::capacity () const {
65+ return current_capacity;
66+ }
67+ bool MinHeap::empty () const {
68+ return current_size == 0 ;
69+ }
70+
71+ void MinHeap::clear () {
72+ current_size = 0 ;
73+ }
74+ void MinHeap::reserve (int newCapacity) {
75+ if (newCapacity <= 0 || newCapacity <= current_capacity) return ;
76+
77+ int *newData = new int [newCapacity];
78+ for (int i=0 ; i<current_size; i++) {
79+ newData[i] = data[i];
80+ }
81+ delete[] data;
82+ data = newData;
83+ current_capacity = newCapacity;
84+ }
85+ void MinHeap::siftUp (int index) {
86+ while (index > 0 ) {
87+ int parent = (index-1 ) / 2 ;
88+ if (data[parent] < data[index]) break ;
89+ swap (data[parent], data[index]);
90+ index = parent;
91+ }
92+ }
93+ void MinHeap::siftDown (int index) {
94+ while (index < current_size) {
95+ int left = index * 2 + 1 ;
96+ int right = index * 2 + 2 ;
97+ int smallest = index;
98+
99+ if (left < current_size && data[left] < data[smallest]) {
100+ smallest = left;
101+ }
102+
103+ if (right < current_size && data[right] < data[smallest]) {
104+ smallest = right;
105+ }
106+
107+ if (smallest == index) break ;
108+
109+ swap (data[index], data[smallest]);
110+ index = smallest;
111+ }
112+ }
113+ int main () {
114+ MinHeap heap;
115+
116+ // 1. 초기 상태
117+ assert (heap.empty ());
118+ assert (heap.size () == 0 );
119+ assert (heap.capacity () == 0 );
120+
121+ // 2. 빈 힙 pop
122+ heap.pop ();
123+
124+ assert (heap.empty ());
125+ assert (heap.size () == 0 );
126+
127+ // 3. 빈 힙 top 예외
128+ bool exceptionThrown = false ;
129+
130+ try {
131+ heap.top ();
132+ } catch (const std::out_of_range&) {
133+ exceptionThrown = true ;
134+ }
135+
136+ assert (exceptionThrown);
137+
138+ // 4. 첫 push
139+ heap.push (30 );
140+
141+ assert (!heap.empty ());
142+ assert (heap.size () == 1 );
143+ assert (heap.capacity () == 1 );
144+ assert (heap.top () == 30 );
145+
146+ // 5. siftUp 확인
147+ heap.push (20 );
148+
149+ assert (heap.size () == 2 );
150+ assert (heap.capacity () == 2 );
151+ assert (heap.top () == 20 );
152+
153+ heap.push (10 );
154+
155+ assert (heap.size () == 3 );
156+ assert (heap.capacity () == 4 );
157+ assert (heap.top () == 10 );
158+
159+ heap.push (40 );
160+ heap.push (5 );
161+
162+ assert (heap.size () == 5 );
163+ assert (heap.capacity () == 8 );
164+ assert (heap.top () == 5 );
165+
166+ // 현재 값:
167+ // 30, 20, 10, 40, 5
168+ // 최소 힙 top은 5
169+
170+ // 6. 중복값 삽입
171+ heap.push (5 );
172+ heap.push (10 );
173+
174+ assert (heap.size () == 7 );
175+ assert (heap.top () == 5 );
176+
177+ // 7. top 참조 반환 확인
178+ // 주의: top 값을 직접 수정하면 힙 조건이 깨질 수 있음
179+ int & topRef = heap.top ();
180+ assert (topRef == 5 );
181+
182+ // 8. pop 순서 확인
183+ int expected1[] = {5 , 5 , 10 , 10 , 20 , 30 , 40 };
184+
185+ for (int value : expected1) {
186+ assert (!heap.empty ());
187+ assert (heap.top () == value);
188+ heap.pop ();
189+ }
190+
191+ assert (heap.empty ());
192+ assert (heap.size () == 0 );
193+ assert (heap.capacity () == 8 );
194+
195+ // 9. pop 이후 재사용
196+ heap.push (100 );
197+ heap.push (50 );
198+ heap.push (75 );
199+ heap.push (25 );
200+
201+ assert (heap.size () == 4 );
202+ assert (heap.top () == 25 );
203+
204+ int expected2[] = {25 , 50 , 75 , 100 };
205+
206+ for (int value : expected2) {
207+ assert (heap.top () == value);
208+ heap.pop ();
209+ }
210+
211+ assert (heap.empty ());
212+
213+ // 10. reserve 직접 호출
214+ heap.reserve (20 );
215+
216+ assert (heap.capacity () == 20 );
217+ assert (heap.size () == 0 );
218+
219+ heap.push (8 );
220+ heap.push (3 );
221+ heap.push (6 );
222+ heap.push (1 );
223+ heap.push (7 );
224+
225+ assert (heap.size () == 5 );
226+ assert (heap.capacity () == 20 );
227+ assert (heap.top () == 1 );
228+
229+ // 작은 reserve는 무시
230+ heap.reserve (10 );
231+
232+ assert (heap.capacity () == 20 );
233+ assert (heap.size () == 5 );
234+ assert (heap.top () == 1 );
235+
236+ // 같은 capacity도 무시
237+ heap.reserve (20 );
238+
239+ assert (heap.capacity () == 20 );
240+ assert (heap.size () == 5 );
241+
242+ // 11. clear
243+ int previousCapacity = heap.capacity ();
244+
245+ heap.clear ();
246+
247+ assert (heap.empty ());
248+ assert (heap.size () == 0 );
249+ assert (heap.capacity () == previousCapacity);
250+
251+ // clear 후 재사용
252+ heap.push (4 );
253+ heap.push (2 );
254+ heap.push (9 );
255+ heap.push (1 );
256+
257+ assert (heap.size () == 4 );
258+ assert (heap.top () == 1 );
259+ assert (heap.capacity () == previousCapacity);
260+
261+ // 12. 오름차순 pop 검증
262+ int expected3[] = {1 , 2 , 4 , 9 };
263+
264+ for (int value : expected3) {
265+ assert (heap.top () == value);
266+ heap.pop ();
267+ }
268+
269+ assert (heap.empty ());
270+
271+ // 13. 내림차순 삽입
272+ for (int i = 100 ; i >= 1 ; i--) {
273+ heap.push (i);
274+ }
275+
276+ assert (heap.size () == 100 );
277+ assert (heap.top () == 1 );
278+
279+ for (int expected = 1 ; expected <= 100 ; expected++) {
280+ assert (heap.top () == expected);
281+ heap.pop ();
282+ }
283+
284+ assert (heap.empty ());
285+ assert (heap.size () == 0 );
286+
287+ // 14. 오름차순 삽입
288+ for (int i = 1 ; i <= 100 ; i++) {
289+ heap.push (i);
290+ }
291+
292+ assert (heap.size () == 100 );
293+ assert (heap.top () == 1 );
294+
295+ for (int expected = 1 ; expected <= 100 ; expected++) {
296+ assert (heap.top () == expected);
297+ heap.pop ();
298+ }
299+
300+ assert (heap.empty ());
301+
302+ // 15. 음수와 중복값
303+ int values[] = {
304+ 0 , -10 , 5 , -3 , -10 , 8 , 2 , -1
305+ };
306+
307+ for (int value : values) {
308+ heap.push (value);
309+ }
310+
311+ int expected4[] = {
312+ -10 , -10 , -3 , -1 , 0 , 2 , 5 , 8
313+ };
314+
315+ for (int value : expected4) {
316+ assert (heap.top () == value);
317+ heap.pop ();
318+ }
319+
320+ assert (heap.empty ());
321+
322+ // 16. 원소 하나에서 pop
323+ heap.push (42 );
324+
325+ assert (heap.size () == 1 );
326+ assert (heap.top () == 42 );
327+
328+ heap.pop ();
329+
330+ assert (heap.empty ());
331+ assert (heap.size () == 0 );
332+
333+ // 빈 상태에서 여러 번 pop
334+ heap.pop ();
335+ heap.pop ();
336+
337+ assert (heap.empty ());
338+
339+ cout << " ALL TESTS PASSED\n " ;
340+
341+ return 0 ;
342+ }
0 commit comments