diff --git a/problem-1/01-bubble-sort.png b/problem-1/01-bubble-sort.png new file mode 100644 index 0000000..0a2b9a8 Binary files /dev/null and b/problem-1/01-bubble-sort.png differ diff --git a/problem-1/README.md b/problem-1/README.md index 99c4ed7..240e6bd 100644 --- a/problem-1/README.md +++ b/problem-1/README.md @@ -14,6 +14,8 @@ ``` 2. 버블 정렬의 코드를 보고 어떻게 동작하는지 그림을 그려보세요. 마찬가지로 위의 값이 주어졌다고 했을 때 코드를 따라가며 그림을 그려가며 이해해 보세요. +![01-bubble-sort.png](01-bubble-sort.png) + 3. 버블 정렬의 코드를 직접 구현해 주세요. diff --git a/problem-1/problem-1.test.js b/problem-1/problem-1.test.js index f54f840..0235fe6 100644 --- a/problem-1/problem-1.test.js +++ b/problem-1/problem-1.test.js @@ -1,4 +1,26 @@ +const exchange = (array, index1, index2) => { + [array[index1], array[index2]] = [array[index2], array[index1]]; +}; + +const isFirstBiggerThanSecond = (a, b) => a > b; const bubbleSort = (array) => { + const { length } = array; + + for (let pass = 1; pass <= length; pass++) { + let exchangeCount = 0; + + for (let index = 0; index < length - pass; index++) { + if (isFirstBiggerThanSecond(array[index], array[index + 1])) { + exchange(array, index, index + 1); + exchangeCount++; + } + } + + // todo : 정렬이 완료됐다면 loop 를 종료한다. + if (exchangeCount === 0) { + break; + } + } }; test.each([ diff --git a/problem-2/02-selection-sort.jpeg b/problem-2/02-selection-sort.jpeg new file mode 100644 index 0000000..058254a Binary files /dev/null and b/problem-2/02-selection-sort.jpeg differ diff --git a/problem-2/README.md b/problem-2/README.md index a5996a6..9f139db 100644 --- a/problem-2/README.md +++ b/problem-2/README.md @@ -13,5 +13,7 @@ ``` 2. 선택 정렬의 코드를 보고 어떻게 동작하는지 그림을 그려보세요. 마찬가지로 위의 값이 주어졌다고 했을 때 코드를 따라가며 그림을 그려가며 이해해 보세요. +![02-selection-sort.jpeg](02-selection-sort.jpeg) + 3. 선택 정렬의 코드를 직접 구현해 주세요. diff --git a/problem-2/problem-2.test.js b/problem-2/problem-2.test.js index 1e1fe4f..53a864a 100644 --- a/problem-2/problem-2.test.js +++ b/problem-2/problem-2.test.js @@ -1,4 +1,27 @@ +const exchange = (array, index1, index2) => { + [array[index1], array[index2]] = [array[index2], array[index1]]; +}; + +const isFirstLesserThanSecond = (a, b) => a < b; + +const findMinValueIndex = (array, startIndex) => { + let minValueIndex = startIndex; + + for (let index = startIndex + 1; index < array.length; index++) { + if (isFirstLesserThanSecond(array[index], array[minValueIndex])) { + minValueIndex = index; + } + } + + return minValueIndex; +}; + const selectionSort = (array) => { + for (let index = 0; index < array.length - 1; index++) { + const minValueIndex = findMinValueIndex(array, index); + + exchange(array, index, minValueIndex); + } }; test.each([ diff --git a/problem-3/03-insertion-sort.png b/problem-3/03-insertion-sort.png new file mode 100644 index 0000000..9441431 Binary files /dev/null and b/problem-3/03-insertion-sort.png differ diff --git a/problem-3/README.md b/problem-3/README.md index 02ba68a..ca1090d 100644 --- a/problem-3/README.md +++ b/problem-3/README.md @@ -13,5 +13,7 @@ ``` 2. 삽입 정렬의 코드를 보고 어떻게 동작하는지 그림을 그려보세요. 마찬가지로 위의 값이 주어졌다고 했을 때 코드를 따라가며 그림을 그려가며 이해해 보세요. +![03-insertion-sort.png](03-insertion-sort.png) + 3. 삽입 정렬의 코드를 직접 구현해 주세요. diff --git a/problem-3/problem-3.test.js b/problem-3/problem-3.test.js index e4450b5..a645225 100644 --- a/problem-3/problem-3.test.js +++ b/problem-3/problem-3.test.js @@ -1,4 +1,19 @@ +const exchange = (array, index1, index2) => { + [array[index1], array[index2]] = [array[index2], array[index1]]; +}; + +const isFirstLesserThanSecond = (a, b) => a < b; const insertionSort = (array) => { + for (let currentIndex = 1; currentIndex < array.length; currentIndex++) { + for (let comparisonIndex = currentIndex; comparisonIndex > 0; comparisonIndex--) { + if (isFirstLesserThanSecond(array[comparisonIndex], array[comparisonIndex - 1])) { + exchange(array, comparisonIndex, comparisonIndex - 1); + } else { + // todo: 비교했을 때 왼쪽보다 작지 않다면 비교를 중지하고, 다음 index 로 넘어간다. + break; + } + } + } }; test.each([ diff --git a/problem-4/04-shell-sort.png b/problem-4/04-shell-sort.png new file mode 100644 index 0000000..ae8b44a Binary files /dev/null and b/problem-4/04-shell-sort.png differ diff --git a/problem-4/problem-4.test.js b/problem-4/problem-4.test.js index 069ccdf..7bc2e99 100644 --- a/problem-4/problem-4.test.js +++ b/problem-4/problem-4.test.js @@ -1,4 +1,27 @@ +const exchange = (array, index1, index2) => { + [array[index1], array[index2]] = [array[index2], array[index1]]; +}; + +const isFirstLesserThanSecond = (a, b) => a < b; + const shellSort = (array) => { + const { length } = array; + + let gap = Math.floor(length / 2); + + while (gap > 0) { + for (let index = gap; index < length; index++) { + for (let previousIndex = index; previousIndex >= 0; previousIndex = previousIndex - gap) { + if (isFirstLesserThanSecond(array[previousIndex], array[previousIndex - gap])) { + exchange(array, previousIndex, previousIndex - gap); + } else { + break; + } + } + } + + gap = Math.floor(gap / 2); + } }; test.each([ diff --git a/problem-5/05-merge-sort-01.png b/problem-5/05-merge-sort-01.png new file mode 100644 index 0000000..f1f78a3 Binary files /dev/null and b/problem-5/05-merge-sort-01.png differ diff --git a/problem-5/06-merge-sort-02.jpeg b/problem-5/06-merge-sort-02.jpeg new file mode 100644 index 0000000..7b2429d Binary files /dev/null and b/problem-5/06-merge-sort-02.jpeg differ diff --git a/problem-5/README.md b/problem-5/README.md index 01799bb..e11b4b9 100644 --- a/problem-5/README.md +++ b/problem-5/README.md @@ -12,5 +12,6 @@ ``` 2. 머지 정렬의 코드를 보고 어떻게 동작하는지 그림을 그려보세요. 마찬가지로 위의 값이 주어졌다고 했을 때 코드를 따라가며 그림을 그려가며 이해해 보세요. - +![05-merge-sort-01.png](05-merge-sort-01.png) +![06-merge-sort-02.jpeg](06-merge-sort-02.jpeg) 3. 머지 정렬의 코드를 직접 구현해 주세요. diff --git a/problem-5/merge-sort-bottomUp.js b/problem-5/merge-sort-bottomUp.js index a5425b1..1072a8d 100644 --- a/problem-5/merge-sort-bottomUp.js +++ b/problem-5/merge-sort-bottomUp.js @@ -1,20 +1,5 @@ const less = (a, b) => a < b; -const mergeSortBottomUp = (list) => { - const { length } = list; - - for (let n = 1; n < length; n = n * 2) { - for (let start = 0; start < length - n; start = start + n * 2) { - merge( - list, - start, - start + (n - 1), - Math.min(start + ((n * 2) - 1), length - 1), - ); - } - } -}; - const merge = (list, start, mid, end) => { let left = start; let right = mid + 1; @@ -37,6 +22,20 @@ const merge = (list, start, mid, end) => { } } }; +const mergeSortBottomUp = (list) => { + const { length } = list; + + for (let n = 1; n < length; n = n * 2) { + for (let start = 0; start < length - n; start = start + n * 2) { + merge( + list, + start, + start + (n - 1), + Math.min(start + ((n * 2) - 1), length - 1), + ); + } + } +}; module.exports = { mergeSortBottomUp, diff --git a/problem-5/merge-sort.js b/problem-5/merge-sort.js index fe56505..86ee617 100644 --- a/problem-5/merge-sort.js +++ b/problem-5/merge-sort.js @@ -1,17 +1,5 @@ const less = (a, b) => a < b; -const mergeSort = (list, start = 0, end = list.length - 1) => { - if (start >= end) { - return; - } - - const mid = Math.floor((start + end) / 2); - - mergeSort(list, start, mid); - mergeSort(list, mid + 1, end); - merge(list, start, mid, end); -}; - const merge = (list, start, mid, end) => { let left = start; let right = mid + 1; @@ -34,6 +22,17 @@ const merge = (list, start, mid, end) => { } } }; +const mergeSort = (list, start = 0, end = list.length - 1) => { + if (start >= end) { + return; + } + + const mid = Math.floor((start + end) / 2); + + mergeSort(list, start, mid); + mergeSort(list, mid + 1, end); + merge(list, start, mid, end); +}; module.exports = { mergeSort, diff --git a/problem-5/problem-5.test.js b/problem-5/problem-5.test.js index 124ce9e..3f44e6b 100644 --- a/problem-5/problem-5.test.js +++ b/problem-5/problem-5.test.js @@ -1,4 +1,39 @@ -const mergeSort = (array) => { +const isFirstLesserThanSecond = (a, b) => a < b; +const merge = (list, start, mid, end) => { + let left = start; + let right = mid + 1; + + const temp = [...list]; + + for (let index = start; index <= end; index++) { + if (left > mid) { // 왼쪽의 정렬이 모두 끝났는가? -> 오른쪽 항목들을 채운다. + list[index] = temp[right]; + right++; + } else if (right > end) { // 오른쪽의 정렬이 모두 끝났는가? -> 왼쪽 항목들을 채운다. + list[index] = temp[left]; + left++; + } else if (isFirstLesserThanSecond(temp[left], temp[right])) { + // 왼쪽과 오른쪽의 항목 중 왼쪽 값이 더 작으면 넣는다. + list[index] = temp[left]; + left++; + } else { + // 왼쪽과 오른쪽의 항목 중 오른쪽 값이 더 작으면 넣는다. + list[index] = temp[right]; + right++; + } + } +}; + +const mergeSort = (list, start = 0, end = list.length - 1) => { + if (start >= end) { + return; + } + + const mid = Math.floor((start + end) / 2); + + mergeSort(list, start, mid); // 절반으로 나눈 왼쪽 리스트를 정렬 + mergeSort(list, mid + 1, end); // 절반으로 나눈 오른쪽 리스트를 정렬 + merge(list, start, mid, end); }; test.each([ diff --git a/problem-6/README.md b/problem-6/README.md index 67c9f36..08f57e9 100644 --- a/problem-6/README.md +++ b/problem-6/README.md @@ -14,5 +14,13 @@ ``` 2. 퀵 정렬의 코드를 보고 어떻게 동작하는지 그림을 그려보세요. 마찬가지로 위의 값이 주어졌다고 했을 때 코드를 따라가며 그림을 그려가며 이해해 보세요. +![quick-sort-code-01.png](quick-sort-code-01.png) +![quick-sort-code-02.png](quick-sort-code-02.png) +![quick-sort-code-03.png](quick-sort-code-03.png) +![quick-sort-code-04.png](quick-sort-code-04.png) +![quick-sort-code-05.png](quick-sort-code-05.png) +![quick-sort-code-06.png](quick-sort-code-06.png) +![quick-sort-code-07.png](quick-sort-code-07.png) +![quick-sort-code-08.png](quick-sort-code-08.png) 3. 퀵 정렬의 코드를 직접 구현해 주세요. diff --git a/problem-6/problem-6.test.js b/problem-6/problem-6.test.js index f335a1f..844b662 100644 --- a/problem-6/problem-6.test.js +++ b/problem-6/problem-6.test.js @@ -1,4 +1,65 @@ +const isFirstLesserThanSecond = (a, b) => a < b; + +const exchange = (array, index1, index2) => { + [array[index1], array[index2]] = [array[index2], array[index1]]; +}; +const shuffle = (array) => { + let randomIndex; + + for (let i = array.length; i > 0; i--) { + randomIndex = Math.floor(Math.random() * i); + i--; + + [array[i], array[randomIndex]] = [array[randomIndex], array[i]]; + } +}; + +const partition = (array, low, high) => { + let left = low + 1; + let right = high; + + const pivot = array[low]; + + while (true) { + while (isFirstLesserThanSecond(array[left], pivot)) { + if (left === high) { + break; + } + + left++; + } + + while (isFirstLesserThanSecond(pivot, array[right])) { + if (right === low) { + break; + } + + right--; + } + + if (left >= right) { + break; + } + + exchange(array, left, right); + } + + exchange(array, low, right); + return right; +}; +const sort = (array, low, high) => { + if (low >= high) { + return; + } + + const partitionIndex = partition(array, low, high); + sort(array, low, partitionIndex - 1); + sort(array, partitionIndex + 1, high); +}; + const quickSort = (array) => { + shuffle(array); + sort(array, 0, array.length - 1); }; test.each([ diff --git a/problem-6/quick-sort-code-01.png b/problem-6/quick-sort-code-01.png new file mode 100644 index 0000000..5e60e65 Binary files /dev/null and b/problem-6/quick-sort-code-01.png differ diff --git a/problem-6/quick-sort-code-02.png b/problem-6/quick-sort-code-02.png new file mode 100644 index 0000000..b095e8c Binary files /dev/null and b/problem-6/quick-sort-code-02.png differ diff --git a/problem-6/quick-sort-code-03.png b/problem-6/quick-sort-code-03.png new file mode 100644 index 0000000..f7e645b Binary files /dev/null and b/problem-6/quick-sort-code-03.png differ diff --git a/problem-6/quick-sort-code-04.png b/problem-6/quick-sort-code-04.png new file mode 100644 index 0000000..4196895 Binary files /dev/null and b/problem-6/quick-sort-code-04.png differ diff --git a/problem-6/quick-sort-code-05.png b/problem-6/quick-sort-code-05.png new file mode 100644 index 0000000..bc25540 Binary files /dev/null and b/problem-6/quick-sort-code-05.png differ diff --git a/problem-6/quick-sort-code-06.png b/problem-6/quick-sort-code-06.png new file mode 100644 index 0000000..0edd2c0 Binary files /dev/null and b/problem-6/quick-sort-code-06.png differ diff --git a/problem-6/quick-sort-code-07.png b/problem-6/quick-sort-code-07.png new file mode 100644 index 0000000..111ca12 Binary files /dev/null and b/problem-6/quick-sort-code-07.png differ diff --git a/problem-6/quick-sort-code-08.png b/problem-6/quick-sort-code-08.png new file mode 100644 index 0000000..e961931 Binary files /dev/null and b/problem-6/quick-sort-code-08.png differ diff --git a/problem-7/README.md b/problem-7/README.md index 0fc24a8..afcf667 100644 --- a/problem-7/README.md +++ b/problem-7/README.md @@ -13,5 +13,14 @@ ``` 2. 힙 정렬의 코드를 보고 어떻게 동작하는지 그림을 그려보세요. 마찬가지로 위의 값이 주어졌다고 했을 때 코드를 따라가며 그림을 그려가며 이해해 보세요. +![heap-sort.png](heap-sort.png) +![heap-sort-sink-01.png](heap-sort-sink-01.png) +![heap-sort-sink-02.png](heap-sort-sink-02.png) +![heap-sort-sink-03-01.png](heap-sort-sink-03-01.png) +![heap-sort-sink-03-02.png](heap-sort-sink-03-02.png) +![heap-sort-sink-04-01.png](heap-sort-sink-04-01.png) +![heap-sort-sink-04-02.png](heap-sort-sink-04-02.png) +![heap-sort-sink-04-03.png](heap-sort-sink-04-03.png) +![heap-sort-sink-05.png](heap-sort-sink-05.png) 3. 힙 정렬의 코드를 직접 구현해 주세요. diff --git a/problem-7/heap-sort-sink-01.png b/problem-7/heap-sort-sink-01.png new file mode 100644 index 0000000..8626a43 Binary files /dev/null and b/problem-7/heap-sort-sink-01.png differ diff --git a/problem-7/heap-sort-sink-02.png b/problem-7/heap-sort-sink-02.png new file mode 100644 index 0000000..7fe3b22 Binary files /dev/null and b/problem-7/heap-sort-sink-02.png differ diff --git a/problem-7/heap-sort-sink-03-01.png b/problem-7/heap-sort-sink-03-01.png new file mode 100644 index 0000000..3c98779 Binary files /dev/null and b/problem-7/heap-sort-sink-03-01.png differ diff --git a/problem-7/heap-sort-sink-03-02.png b/problem-7/heap-sort-sink-03-02.png new file mode 100644 index 0000000..6cc6a67 Binary files /dev/null and b/problem-7/heap-sort-sink-03-02.png differ diff --git a/problem-7/heap-sort-sink-04-01.png b/problem-7/heap-sort-sink-04-01.png new file mode 100644 index 0000000..4c4ba6b Binary files /dev/null and b/problem-7/heap-sort-sink-04-01.png differ diff --git a/problem-7/heap-sort-sink-04-02.png b/problem-7/heap-sort-sink-04-02.png new file mode 100644 index 0000000..bd5fd1b Binary files /dev/null and b/problem-7/heap-sort-sink-04-02.png differ diff --git a/problem-7/heap-sort-sink-04-03.png b/problem-7/heap-sort-sink-04-03.png new file mode 100644 index 0000000..9f089c6 Binary files /dev/null and b/problem-7/heap-sort-sink-04-03.png differ diff --git a/problem-7/heap-sort-sink-05.png b/problem-7/heap-sort-sink-05.png new file mode 100644 index 0000000..f787e34 Binary files /dev/null and b/problem-7/heap-sort-sink-05.png differ diff --git a/problem-7/heap-sort.png b/problem-7/heap-sort.png new file mode 100644 index 0000000..efaade4 Binary files /dev/null and b/problem-7/heap-sort.png differ diff --git a/problem-7/problem-7.test.js b/problem-7/problem-7.test.js index 8d36fec..b5d7ca5 100644 --- a/problem-7/problem-7.test.js +++ b/problem-7/problem-7.test.js @@ -1,4 +1,37 @@ +const exchange = (array, a, b) => { + [array[a], array[b]] = [array[b], array[a]]; +}; + +const less = (a, b) => a < b; + +const sink = (array, i, N) => { + while (2 * i <= N) { + let j = 2 * i; + if (j < N && less(array[j], array[j + 1])) { + j++; + } + + if (!less(array[i], array[j])) { + break; + } + + exchange(array, i, j); + i = j; + } +}; + const heapSort = (array) => { + let N = array.length - 1; + + for (let i = Math.floor(N / 2); i >= 1; i--) { + sink(array, i, N); + } + + while (N > 1) { + exchange(array, 1, N); + N--; + sink(array, 1, N); + } }; test.each([