DataStructure/Algorithm

Bucket Sort (버킷 정렬)

S0LL 2024. 9. 23. 12:38

버킷 정렬이란?

bucket은 바구니를 의미합니다. 

말 그래도 버킷 정렬은 바구니에 데이터를 담는 형태를 닮았다 하여 이름 붙여졌습니다.

위 그림과 같이 숫자를 카테로리별로 나눠 바구니에 담은 뒤,

그 바구니 안을 정렬해주는 방식입니다.

 

바구니 안을 정렬할 때는 앞에서 배웠던 정렬 방식 중 아무거나 사용하셔도 상관 없습니다.

 

저는 삽입 정렬을 이용해서 버킷 정렬을 구현해보았습니다.

 

 

코드)

디버깅, 실행할 때 보기 편하도록 

버킷을 출력해주는 함수를 추가해주었습니다.

#include <iostream>
#include <vector>

void Print(std::vector<float>& v) {
  for (auto& a : v) {
    std::cout << a << " ";
  }
  std::cout << '\n';
}

void PrintBucket(std::vector<std::vector<float>>& v) {
  for (int i = 0; i < v.size(); i++) {
    std::cout << i << ": ";
    for (int j = 0; j < v[i].size(); j++) {
      std::cout << v[i][j] << " ";
    }
    std::cout << '\n';
  }
}

void InsertionSort(std::vector<float>& v) {
  for (int i = 0; i < v.size(); i++) {
    float key = v[i];
    int j = i - 1;
    while (j >= 0 && v[j] > key) {
      v[j + 1] = v[j];
      j--;
    }
    v[j + 1] = key;
  }
}

void BucketSort(std::vector<float>& v, int num_buckets) {
  std::vector<std::vector<float>> buckets(num_buckets);

  for (auto a : v) {
    int idx = int(num_buckets * a);
    buckets[idx].push_back(a);
  }

  std::cout << "Before sorting" << '\n';
  PrintBucket(buckets);

  for (int i = 0; i < num_buckets; i++) {
    InsertionSort(buckets[i]);
  }

  std::cout << "After sorting" << '\n';
  PrintBucket(buckets);

  int index = 0;
  for (int i = 0; i < num_buckets; i++) {
    for (auto j : buckets[i]) {
      v[index++] = j;
    }
  }
}

 

10의자릿수대로 분류해주고 각 바구니를 정렬해주는 방식이라 구현은 어렵지 않게 할 수 있을 것 같습니다.

 

버킷 정렬의 시간 복잡도)

 

이를 이해하기 위해서는 기댓값과 분산에 대한 이해가 필요하다.

 

-기댓값과 분산의 상관관계

 

위와 같이 기댓값으로부터 분산을 구할 수 있습니다.

 

이것 말고도 이항분포에 대한 간단한 이해도 필요합니다.

 

 

 

-이항 분포

위의 기댓값과 분산을 구하는 것은 X가 이항분포 n,p를 따를 때의 성질을 이용한 것입니다.

 

 

이제는 시간 복잡도에 대해 알아보도록 하겠습니다.

 

-평균 시간

버킷의 개수와 입력의 개수 모두 n개라고 가정했을 때 평균 시간복잡도는 𝜭(n)인 것을 확인할 수 있습니다.

 

그렇다면 최악의 경우는 어떨까요??

 

만약 모든 입력의 카테고리가 같아서 모두 하나의 바구니로 들어간다면 어떨까요?

 

그럴 때는 그냥 한 바구니에 있는 전체 데이터를 정렬해주는 것이므로 다른 정렬과 다를 바가 없습니다.

 

따라서 최악의 경우에는 O(n^2) 이라고 할 수 있습니다.

'DataStructure > Algorithm' 카테고리의 다른 글

Dynamic programming 연습문제  (0) 2024.10.17
Dynamic Programming  (4) 2024.10.17
3-way QuickSort (3분할 퀵정렬)  (0) 2024.09.16
QuickSort (퀵정렬)  (0) 2024.09.16
MergeSort (병합 정렬)  (2) 2024.09.15