Skip to content

김승우 3주차 과제 구현 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
19 changes: 19 additions & 0 deletions problem-1/problem-1.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
const bubbleSort = (array) => {
let exchangeCount = 0;

// i = 정렬이 완료될 원소의 개수
// 첫 패스 때 1개의 정렬이 완료됨
// 마지막 패스 때 array.length - 1개의 원소가 정렬됨
// array.length - 1개가 원소가 정렬되면 마지막 원소는 정렬할 필요가 없다.
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
exchangeCount += 1;

[array[j + 1], array[j]] = [array[j], array[j + 1]];
}
}

if (i === 0 && exchangeCount === 0) {
return;
}
}
Comment on lines +8 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

바깥 for문과 안쪽 for문이 있는데, 안쪽 for문에서 한 번도 교환이 일어나지 않았다면, 정렬되어있다는 것을 확신할 수 있습니다.

  for (let i = 0; i < array.length; i++) {
    let exchangeCount = 0;

    for (let j = 0; j < array.length - 1 - i; j++) {
      if (array[j] > array[j + 1]) {
        exchangeCount += 1;

        [array[j + 1], array[j]] = [array[j], array[j + 1]];
      }
    }

    if (exchangeCount === 0) {
      return;
    }
  }

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다!! 굳이 i === 0을 할 필요가 없었네요!

};

test.each([
Expand Down
25 changes: 25 additions & 0 deletions problem-2/problem-2.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
const exchange = (array, a, b) => {
[array[b], array[a]] = [array[a], array[b]];
};

const less = (a, b) => a < b;

const findMinIndex = (array, startIndex) => {
let minIndex = startIndex;

for (let i = startIndex; i < array.length; i++) {
if (less(array[i], array[minIndex])) {
minIndex = i;
}
}

return minIndex;
};

const selectionSort = (array) => {
for (let i = 0; i < array.length - 1; i++) {
const minIndex = findMinIndex(array, i);

if (i !== minIndex) {
exchange(array, i, minIndex);
}
}
};

test.each([
Expand Down
15 changes: 15 additions & 0 deletions problem-3/problem-3.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
const exchange = (array, a, b) => {
[array[b], array[a]] = [array[a], array[b]];
};

const less = (a, b) => a < b;

const insertionSort = (array) => {
for (let i = 1; i < array.length; i++) {
for (let j = i; j > 0; j--) {
if (less(array[j], array[j - 1])) {
exchange(array, j, j - 1);
} else {
break;
}
}
}
};

test.each([
Expand Down
24 changes: 23 additions & 1 deletion problem-4/problem-4.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
const shellSort = (array) => {
const exchange = (list, a, b) => {
[list[b], list[a]] = [list[a], list[b]];
};

const less = (a, b) => a < b;

const shellSort = (list) => {
let h = 1;
const { length } = list;

while (h < (length / 3)) {
h = (3 * h) + 1;
}

for (let k = h; k >= 1; k = Math.floor(k / 3)) {
for (let i = k; i < length; i++) {
for (let j = i; j >= k; j--) {
if (less(list[j], list[j - k])) {
exchange(list, j, j - k);
}
}
}
}
};

test.each([
Expand Down
32 changes: 31 additions & 1 deletion problem-5/problem-5.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
const mergeSort = (array) => {
const less = (a, b) => a < b;

const merge = (array, start, mid, end) => {
let left = start;
let right = mid + 1;

const temp = [...array];

for (let i = start; i <= end; i++) {
if (left > mid) {
array[i] = temp[right++];
} else if (right > end) {
array[i] = temp[left++];
} else if (less(temp[left], temp[right])) {
array[i] = temp[left++];
} else {
array[i] = temp[right++];
}
}
};

const mergeSort = (array = [], start = 0, end = array.length - 1) => {
if (start >= end) {
return;
}

const mid = Math.floor((start + end) / 2);

mergeSort(array, start, mid);
mergeSort(array, mid + 1, end);
merge(array, start, mid, end);
};

test.each([
Expand Down
67 changes: 66 additions & 1 deletion problem-6/problem-6.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,69 @@
const quickSort = (array) => {
const exchange = (array, a, b) => {
[array[b], array[a]] = [array[a], array[b]];
};

/**
* 1. 하나의 배열에 대해서 퀵 정렬을 실행
* 2. pivot의 위치를 결정한다
* 3. pivot의 위치를 기준으로 왼쪽, 오른쪽 부분 배열을 만든다
* 4. 왼쪽, 오른쪽 부분 배열에 대해서 퀵 정렬을 실행한다
*/
const quickSort = (array, start, end) => {
const startIndex = start || 0;
const endIndex = end || array.length - 1;

const length = endIndex - startIndex + 1;

if (length <= 1) {
return;
}

const pivot = array[startIndex];

let left = startIndex;
let right = endIndex;

while (right > left) {
for (left; left <= endIndex; left++) {
if (pivot < array[left]) {
break;
}
}

if (left > endIndex) {
left = endIndex;
}

for (right; right >= startIndex; right--) {
if (pivot >= array[right]) {
break;
}
}

if (right < startIndex) {
right = startIndex;
}

if (right <= left) {
break;
}

exchange(array, left, right);
}

const pivotIndex = right;

exchange(array, pivotIndex, startIndex);

// 왼쪽 배열
if (pivotIndex - 1 >= startIndex) {
quickSort(array, startIndex, pivotIndex - 1);
}

// 오른쪽 배열
if (pivotIndex + 1 <= endIndex) {
quickSort(array, pivotIndex + 1, endIndex);
}
};

test.each([
Expand Down
44 changes: 44 additions & 0 deletions problem-7/problem-7.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,48 @@
const exchange = (array, a, b) => {
[array[b], array[a]] = [array[a], array[b]];
};

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);

// 마지막 노드는 정렬되었으니 sync할 항목에서 제외
N--;

sink(array, 1, N);
}
};

test.each([
Expand Down