Skip to content
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