본문 바로가기
반응형

Computer Science63

이분 탐색(Binary Search) 데이터가 담긴 리스트를 탐색하는 방법은 크게 순차 탐색(Linear Search)과 이분 탐색(Binary Search)이 존재한다. 예를 들어 { 8, 3, 1, 5, 4, 7, 9, 2, 6, 10}, 10개의 데이터가 담긴 리스트가 있다고 하자. 이 리스트에서 9의 위치를 찾기 위해서는 어떻게 해야 할까? 위 리스트처럼 정렬되지 않은 리스트에서 데이터를 탐색하기 위해서는 어쩔 수 없이 처음부터 끝까지 순차적으로 탐색을 진행하여 9의 위치를 찾는 방법밖에 없을 것이다. ​그렇다면 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}처럼 정렬된 리스트가 있다고 생각해 보자. 이 리스트에서도 9의 위치를 찾기 위해서는 어떻게 해야 할까? 단순하게는 앞서 언급한 방법처럼 처음부터 순차적으로 9의 인덱스.. 2021. 7. 2.
기수 정렬(Radix Sort) 이번에 배워볼 정렬 알고리즘은 기수 정렬(Radix Sort)이다. 지금까지 배워온 정렬들은 모두 데이터들을 비교하여 정렬하는 방식이었다. 기수 정렬은 이와는 다르게 데이터를 비교하지 않고 정렬하는 조금 특수한 정렬 알고리즘이다. 기수 정렬은 O(dn)의 시간 복잡도를 가질 정도로 매우 빠른 정렬 알고리즘이다. 여기서 d는 데이터의 자릿수이다. ​ 기수 정렬은 아쉽게도 추가적인 메모리를 필요로 하며, 정렬할 수 있는 데이터 타입이 제한된다는 단점이 있다. 기수 정렬을 사용하기 위해선 데이터의 값들이 동일한 길이를 가지는 숫자나 문자열로 구성되어 있어야 한다. ​그렇다면 0~99 사이의 숫자들로 이루어진 배열을 정렬하는 과정을 살펴보자. 간단하게 100개의 배열을 생성하여 각 인덱스에 저장하여 출력하는 방.. 2021. 7. 1.
힙 정렬(Heap Sort) 이번에 배워볼 정렬 알고리즘은 힙 정렬(Heap Sort)이다. 이전에 우선순위 큐를 공부할 때 힙 자료구조에 대해서 공부하였다. 힙 자료구조는 우선순위 큐를 완전 이진 트리로 구현하는 방법으로 삽입, 삭제 연산이 O(logN)이라는 빠른 시간에 가능하기 때문에 최대, 최소 등 자신이 원하는 조건에 맞는 데이터를 정렬을 유지한 상태로 빠르게 뽑아낼 수 있는 훌륭한 자료구조였다. 힙의 특성을 활용하여 원하는 기준의 원소부터 차례대로 추출하는 방법을 힙 정렬이라 한다. 예를들어 오름차순으로 데이터를 정렬하려고 한다면 최소 힙을 구현하고 원소들을 아무렇게나 차례대로 삽입한 다음, 루트 노드(최솟값)를 데이터 개수만큼 삭제를 통해 뽑아내서 나열하면 원소들이 오름차순으로 정렬된 것을 확인할 수 있다. ​ 힙 정렬.. 2021. 7. 1.
퀵 정렬(Quick Sort) 이번에 배워볼 정렬 알고리즘은 퀵 정렬(Quick Sort)이다. 퀵 정렬은 평균적으로 매우 빠른 수행 속도를 자랑하는 정렬 방법이다. 퀵 정렬도 앞서 배운 합병 정렬처럼 분할 정복(Divide and Conquer) 방법에 근거한다. 하지만 합병 정렬은 항상 리스트를 절반으로 균등하게 나누는 반면에, 퀵 정렬은 피벗(Pivot)이라는 것을 사용하여 비균등하게 분할한다. 피벗을 기준으로 좌측에는 크기가 작은 요소, 우측에는 크기가 큰 요소들을 옮기면서 분할한다. Mid를 기준으로 좌, 우측으로 분할하는 합병 정렬과 조금 차이가 있다. 피벗을 기준으로 분할된 상태에서 피벗을 제외한 좌측, 우측 요소들을 정렬하면 정렬된 리스트를 얻게 된다. 그럼 퀵 정렬은 분할된 상태에서 어떤 방법으로 리스트를 정렬할까? .. 2021. 7. 1.
합병 정렬(Merge Sort) 이번에 배워볼 정렬 알고리즘은 합병 정렬(Merge Sort)이다. 이전까지 배운 정렬들은 최악의 경우 시간 복잡도가 O(N^2)이지만, 합병 정렬은 이와 다르게 최선, 평균, 최악 모든 경우가 O(N logN)의 시간 복잡도를 가지는 빠른 정렬 알고리즘이다. 합병 정렬은 하나의 리스트를 두 개의 균등한 크기로 분할하고 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 하는 방법이다. 합병 정렬은 분할 정복(Divide and Conquer) 방법에 바탕을 두고 있다. 분할 정복 방법은 문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략이다. ​ 합병 정렬은 다음의 단계들로 이루어진다. 분할(Divide).. 2021. 7. 1.
버블 정렬(Bubble Sort) 이번에 배워볼 정렬 알고리즘은 버블 정렬(Bubble Sort)이다. 버블 정렬은 인접한 2개의 원소를 비교하여 크기가 순서대로 되어 있지 않으면 서로 교환하는 비교-교환 과정을 리스트의 왼쪽 끝에서 시작하여 오른쪽 끝까지 진행하여 정렬하는 알고리즘이다. 선택 정렬과 삽입 정렬은 정렬된 원소들이 좌측에 위치하는 반면, 버블 정렬은 이와 다르게 정렬된 원소들이 우측에 위치하는 차이점이 존재한다. 버블 정렬의 가장 큰 문제점은 순서에 맞지 않은 원소를 인접한 원소와 매번 교환한다는 것이다. 특정 원소가 최종 정렬 위치에 이미 있는 경우라도 교환되는 일이 발생하기 때문에 구현하기가 정말 단순하지만 좋지 못한 성능 때문에 거의 사용되지 않는다. 버블 정렬(Bubble Sort)의 시간 복잡도는 O(N^2)이다... 2021. 7. 1.
삽입 정렬(Insertion Sort) 이번에 배워볼 정렬 알고리즘은 삽입 정렬(Insertion Sort)이다. 삽입 정렬은 손안의 카드를 정렬하는 방법과 유사하다. 새로운 원소를 기존에 정렬된 원소 사이의 올바른 자리를 찾아 삽입함으로써 정렬이 유지되게 한다. 삽입 정렬은 비교적 많은 레코드들의 이동을 포함하기 때문에 레코드 수가 많고 레코드 크기가 클 경우에 적합하지 않음을 알 수 있다. 반면, 안정한 정렬 방법으로서 레코드의 수가 적을 경우 알고리즘 자체가 매우 간단하므로 다른 복잡한 정렬 방법보다 유리할 수 있다. 또한, 삽입 정렬은 대부분의 레코드가 이미 정렬되어 있는 경우에는 매우 효율적일 수 있다. 삽입 정렬(Insertion Sort)의 시간 복잡도는 O(N^2)이다. 다만, 리스트가 이미 정렬되어 있는 상태라면 O(N)의 시.. 2021. 7. 1.
선택 정렬(Selection Sort) 정렬 알고리즘은 알고리즘에서 가장 먼저 배우는 알고리즘이다. 정렬 알고리즘에는 선택 정렬, 삽입 정렬, 버블 정렬, 합병 정렬, 퀵 정렬, 힙 정렬 등 다양한 정렬 알고리즘이 존재한다. 선택, 삽입, 버블 정렬은 구현이 상대적으로 쉽지만 성능이 좋지 않은 반면, 합병, 퀵, 힙 정렬은 구현이 상대적으로 복잡하지만 성능이 훨씬 좋기 때문에 후자의 정렬들을 사용하는 것을 나는 선호하는 편이다. 하지만 성능의 차이를 알기 위해선 모든 정렬 알고리즘의 원리를 알아야한다. 이번에는 선택 정렬(Seletcion Sort)을 다뤄보겠다. 선택 정렬은 주어진 리스트를 돌면서 가장 작은(큰) 원소를 찾아 정렬된 원소를 제외한 제일 앞의 원소와 교환해주면 되기 때문에 가장 이해하기가 쉽고 단순한 정렬 방법이다. 선택 정렬.. 2021. 7. 1.
세그먼트 트리(Segment Tree) 이번에 배워볼 자료구조는 세그먼트 트리(Segement Tree)이다. 최근 코딩 테스트에서 세그먼트 트리를 알고 있다면 조금 더 쉽게 해결할 수 있는 문제들이 나오고 있어서 한번 다뤄보려 한다. 세그먼트 트리는 이해하고 구현하는데 난이도가 상당히 있으며, 아직까지는 굳이 몰라도 된다고 생각하기 때문에 보다가 이해가 안 된다면 과감하게 버리는 것을 추천한다. 세그먼트 트리는 트라이처럼 트리를 활용한 자료구조이다. 세그먼트 트리를 이해하기 위해 사용되는 구간 합 구하기라는 대표적인 문제가 있다. 이 문제를 통해 세그먼트 트리를 이해해 보자. 구간 합 구하기 문제는 N 개의 숫자가 나열돼있을 때 a~b 구간 데이터들의 합을 구하는 문제이다. 구간 합을 구하는 방법은 대표적으로 3가지가 존재한다. 첫 번째는 .. 2021. 6. 30.
반응형