-
Notifications
You must be signed in to change notification settings - Fork 5
[gyim1345] sort 구현 #16
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
gyim1345
wants to merge
1
commit into
itaewon-coding-dojo:master
Choose a base branch
from
gyim1345:sort
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// O(n^2) | ||
// 첫 요소부터 요소를 두개씩 비교 해서 앞 요소가 더 크면 두번째 요소와 자리 바꿈. 모든 요소들을 비교 하고 이 비교를 n 만큼 반복한다. | ||
const bubbleSort = (array) => { | ||
const newArray = [...array]; | ||
newArray.forEach(_ => { | ||
newArray.forEach((e, index) => { | ||
if(newArray[index +1] < e) { | ||
[newArray[index], newArray[index +1]] = [newArray[index + 1], e]; | ||
} | ||
}) | ||
}); | ||
return newArray; | ||
} | ||
|
||
test('bubbleSort', () => { | ||
expect(bubbleSort([2,6,8,4,1,3,7,5])).toEqual([1,2,3,4,5,6,7,8]); | ||
}); | ||
|
||
//O(n^2) | ||
//정렬된 목록과 정렬되지 않은 목록을 동일한 배열에 유지. | ||
//정렬된 목록에 항목을 삽입할 올바른 위치를 찾아 넣음. | ||
const insertionSort = (array, newArray = [], index = 0) => { | ||
if(index === array.length) { | ||
return newArray; | ||
} | ||
const currentElement = array[index]; | ||
return insertionSort(array, insert(newArray,currentElement), index + 1); | ||
} | ||
const insert = (array, element) => { | ||
let index = 0; | ||
const newArray = [...array]; | ||
while(newArray[index] && newArray[index] < element) { | ||
index += 1; | ||
} | ||
newArray.splice(index, 0,element) | ||
return newArray; | ||
} | ||
|
||
|
||
test('insertionSort', () => { | ||
expect(insertionSort([2,6,8,4,1,3,7,5])).toEqual([1,2,3,4,5,6,7,8]); | ||
}); | ||
|
||
//O(n^2) | ||
//(오름차순)첫번째 요소 부터 배열을 모두 탐색하여 최소값을 찾아서 그것과 자리를 바꾼다. n번만큼 반복 | ||
|
||
const selectionSort = (array,currentIndex = 0) => { | ||
if(currentIndex === array.length){ | ||
return array; | ||
} | ||
|
||
const minIndex = array.reduce((acc, cur, index) => { | ||
if(index >= currentIndex && (acc.value === null || acc.value > cur)) { | ||
return {index, value: cur}; | ||
} | ||
return acc; | ||
}, {index: null, value: null}).index | ||
|
||
return selectionSort(swap(array, minIndex, currentIndex), currentIndex +1); | ||
} | ||
|
||
const swap = (array, targetIndex, currentIndex) => { | ||
[array[targetIndex], array[currentIndex]] = [array[currentIndex], array[targetIndex]]; | ||
return array; | ||
} | ||
|
||
test('selectionSort', () => { | ||
expect(selectionSort([2,6,8,4,1,3,7,5])).toEqual([1,2,3,4,5,6,7,8]); | ||
}); | ||
|
||
|
||
// worst case : O(n^2) (이미 정렬이 되어 있는 경우) | ||
// best case : O(n log n) | ||
//임의의 pivot골라서 그 기준으로 작은건 왼쪽 배열, 큰건 오른쪽 배열에 담는다. | ||
//각각 배열을 또 pivot 골라서 같은 작업을 실행한다. | ||
|
||
const quickSort = (array) => { | ||
if(!array[0]) { | ||
return[]; | ||
} | ||
const pivot = array[array.length -1]; | ||
|
||
const {left, right} = array.reduce((acc,cur)=> { | ||
if(cur === pivot) { | ||
return acc; | ||
} | ||
if(cur > pivot ){ | ||
acc.right = [...acc.right, cur]; | ||
return acc; | ||
} | ||
acc.left = [...acc.left, cur]; | ||
return acc | ||
},{'left': [], 'right':[]}) | ||
|
||
return [...quickSort(left), pivot,...quickSort(right)]; | ||
} | ||
|
||
|
||
test('quickSort', () => { | ||
expect(quickSort([2,6,8,4,1,3,7,5])).toEqual([1,2,3,4,5,6,7,8]); | ||
}); | ||
|
||
|
||
//worst case : O(n log n) | ||
//best case : O(n log n) | ||
//배열을 반씩 잘라 나가면서 하나의 요소로 쪼갠 다음 다시 병합시키면서 정렬해 나간다 | ||
//분할과 병합 단계로 나뉘는데 분할 단계는 시간 복잡도에 포함되지 않는다 | ||
|
||
|
||
const mergeSort = (array) => { | ||
if(array.length <= 1) { | ||
return [array[0]]; | ||
} | ||
const midIndex = Math.floor((array.length)/2) | ||
return merge(mergeSort(array.slice(0,midIndex)), mergeSort(array.slice(midIndex))); | ||
} | ||
|
||
const merge = (leftArray = [], rightArray = []) => { | ||
const newArray = []; | ||
while(leftArray[0] || rightArray[0]) { | ||
if(!leftArray[0]) { | ||
newArray.push(rightArray.shift()); | ||
continue; | ||
} | ||
if(!rightArray[0]) { | ||
newArray.push(leftArray.shift()); | ||
continue; | ||
} | ||
if(rightArray[0] > leftArray[0]) { | ||
newArray.push(leftArray.shift()); | ||
continue; | ||
} | ||
newArray.push(rightArray.shift()); | ||
} | ||
return newArray; | ||
} | ||
|
||
test('mergeSort', () => { | ||
expect(mergeSort([2,6,8,4,1,3,7,5])).toEqual([1,2,3,4,5,6,7,8]); | ||
}); | ||
|
||
// test('merge', () => { | ||
// expect(merge([2,6], [4,8])).toEqual([2,4,6,8]); | ||
// }); | ||
|
||
//최선의 경우 : O(n) | ||
// 최악의 경우 : O(n^2) | ||
// gap을 선택하여 첫 요소 부터 해당 gap(간격)에 떨어진 요소들과 비교하여 isertion sort 실행. | ||
// gap을 줄여 나가면서 계속 진행. | ||
|
||
|
||
const shellSort = (array) => { | ||
let newArray = array; | ||
let gap = Math.floor(array.length/2); | ||
while(gap > 0) { | ||
const arrays = []; | ||
for(let currentIndex = 0; currentIndex < gap; currentIndex += 1) { | ||
for(let gapIndex = currentIndex; gapIndex < newArray.length; gapIndex += gap) { | ||
if(arrays[currentIndex]) { | ||
arrays[currentIndex]= [...arrays[currentIndex], newArray[gapIndex]]; | ||
continue; | ||
} | ||
arrays[currentIndex] = [newArray[gapIndex]] | ||
} | ||
} | ||
newArray = arrays.map(array => insertionSort(array)).reduce((acc,cur)=> [...acc, ...cur]); | ||
gap = Math.floor(gap/2); | ||
} | ||
return newArray; | ||
} | ||
|
||
|
||
test('shell', () => { | ||
expect(shellSort([2,6,8,4,1,3,7,5])).toEqual([1,2,3,4,5,6,7,8]); | ||
}); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오?! 재귀로 푸셨네용? ㅎㅎ 👍👍👍👍👍
특히, 꼬리 호출 최적화 인가용??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
최적화는 처음 들어봅니다! 덕분에 배워 갑니다 👍
return 에 다른 연산 안 넣고 재귀만 return 하는 거니깐 꼬리 호출 최적화가 맞죠??