diff --git a/bucketsort b/bucketsort
new file mode 100755
index 0000000000000000000000000000000000000000..6a1dd441d87f5d73ef381536b08bfff4cf258ac3
Binary files /dev/null and b/bucketsort differ
diff --git a/bucketsort.c b/bucketsort.c
new file mode 100644
index 0000000000000000000000000000000000000000..3d9376bf5e8d74cd5ae86e0c72aca30adf024912
--- /dev/null
+++ b/bucketsort.c
@@ -0,0 +1,130 @@
+// Copyright www.computing.llnl.gov 
+#include <stdio.h> 
+#include <stdlib.h> 
+#include <time.h> 
+#include <omp.h>
+#include <assert.h> 
+
+int *create_rand_nums(int num_elements) { 
+    int *rand_nums = (int *)malloc(sizeof(int) * num_elements); 
+    assert(rand_nums != NULL); 
+    int i; 
+    for (i = 0; i < num_elements; i++) { 
+        rand_nums[i] = rand() % num_elements; 
+    } 
+    return rand_nums; 
+}
+
+void insertion_sort(int *array, int num_elements) {
+    int d, c, temp;
+    for (c = 1; c < num_elements; c++) {
+        d = c;
+        while (d > 0 && array[d] < array[d-1]) {
+            temp = array[d];
+            array[d] = array[d-1];
+            array[d-1] = temp;
+            d--;
+        }
+    }
+}
+ 
+int main(int argc, char *argv[])  {
+    if (argc != 3) {
+        printf("Usage: bucketsort thread_counts num_elements\n");
+        exit(1);
+    }
+
+    int i;
+    int thread_counts = strtol(argv[1], NULL, 10);
+    int num_elements = atoi(argv[2]);
+
+    time_t time_count;
+
+    int bucket_range = num_elements / thread_counts;
+    int bucket[num_elements];
+    int count[thread_counts];
+    int iterator[thread_counts];
+    int bucket_index[thread_counts][2];
+
+    // Buat elemen randomm
+    int *rand_nums = NULL;
+    rand_nums = create_rand_nums(num_elements);
+    
+    // Timer
+    time_count = clock();
+
+    
+    // Inisalisasi buckets
+    for (i = 0; i < num_elements; ++i) {
+       bucket[i] = -1;
+    }
+
+    // Inisialisasi count
+    for (i = 0; i < thread_counts; ++i) {
+        count[i] = 0;
+        iterator[i] = 0;
+    }
+
+    // Inisialisasi index
+    for (i = 0; i < thread_counts; ++i) {
+        bucket_index[i][0] = -1;
+        bucket_index[i][1] = -1;
+    }
+
+    // Hitung ukuran yang akan dimiliki oleh setiap bucket
+    for (i = 0; i < num_elements; i++) {
+        count[rand_nums[i]/bucket_range]++;
+    }
+
+    // Hitung index bucket
+    int lastIndex = 0;
+    for (i = 0; i < thread_counts; i++) {
+        if (count[i] != 0) {
+            bucket_index[i][0] = lastIndex;
+            bucket_index[i][1] = bucket_index[i][0] + count[i] - 1;
+            lastIndex += count[i];
+        }
+    }
+
+    // Masukan elemen ke dalam bucket
+    for (i = 0; i < num_elements; i++) {
+        int num_bucket = rand_nums[i] / bucket_range;
+        bucket[bucket_index[num_bucket][0] + iterator[num_bucket]] = rand_nums[i];
+        iterator[num_bucket]++;
+    }
+
+    // debugging purpose
+    // for (i = 0; i < num_elements; i++) {
+    //     printf("%d\n", rand_nums[i]);
+    // }
+
+    // for (i = 0; i < thread_counts; i++) {
+    //     printf("size: %d\n", count[i]);
+    // }
+
+    // for (i = 0; i < thread_counts; i++) {
+    //     printf("index first: %d\n", bucket_index[i][0]);
+    //     printf("index last: %d\n", bucket_index[i][1]);
+    //     printf("\n");
+    // }
+
+    // for (i = 0; i < num_elements; i++) {
+    //     printf("%d\n", bucket[i]);
+    // }
+
+    #pragma omp parallel num_threads(thread_counts)
+    for (i = 0; i < thread_counts; i++) {
+        if (count[i] != 0) {
+            insertion_sort(bucket + bucket_index[i][0], count[i]);
+        }
+    }
+
+    // for (i = 0; i < num_elements; i++) {
+    //     printf("%d\n", bucket[i]);
+    // }
+
+    float final_time = (float) (clock()-time_count) / CLOCKS_PER_SEC *1000;
+    printf("Time : %f ms\n", final_time);
+
+    return 0;
+}
\ No newline at end of file