diff --git a/Praktikum3_13513006_13513074.pdf b/Praktikum3_13513006_13513074.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..516e4d68064c3b6dcba30fc95e6c9ae4c56e054d
Binary files /dev/null and b/Praktikum3_13513006_13513074.pdf differ
diff --git a/bucket_sort.c b/bucket_sort.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d37dbabd9a5ace10b7a793f19b39e0c37f8587f
--- /dev/null
+++ b/bucket_sort.c
@@ -0,0 +1,121 @@
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <omp.h>
+
+const int MAX_VALUE = 2000000;
+
+typedef struct {
+  int* arr;
+  int n;
+  int min;
+  int max;
+} Bucket;
+
+void pushToBucket(Bucket* b, int x) {
+  b->arr[b->n++] = x;
+}
+
+void sort(int* arr, int n) {
+  int c, d, t;
+  for (c = 1 ; c <= n - 1; c++) {
+    d = c;
+
+    while ( d > 0 && arr[d] < arr[d-1]) {
+      t = arr[d];
+      arr[d]   = arr[d-1];
+      arr[d-1] = t;
+
+      d--;
+    }
+  }
+}
+
+int* create_rand_nums(int num_elements, int* min, int* max) {
+    int *rand_nums = (int *)malloc(sizeof(int) * num_elements);
+    int i;
+
+    srand(time(NULL));
+    rand_nums[0] = rand() % MAX_VALUE;
+    *min = rand_nums[0];
+    *max = rand_nums[0];
+
+    for (i = 1; i < num_elements; i++) {
+        rand_nums[i] = rand() % MAX_VALUE;
+        if (*max < rand_nums[i]) {
+          *max = rand_nums[i];
+        }
+        if (*min > rand_nums[i]) {
+          *min = rand_nums[i];
+        }
+    }
+    return rand_nums;
+}
+
+
+int main(int argc, char* argv[]) {
+	if (argc != 3) {
+		fprintf(stderr, "Usage: [num_element] [num_thread]");
+		exit(1);
+	}
+
+	clock_t begin, end;
+  	begin = clock();
+
+	int i, j;
+	int nElement = atoi(argv[1]);
+	int nThread = atoi(argv[2]);
+	int min, max;
+	int* rand_nums = create_rand_nums(nElement, &min, &max);
+
+	Bucket bucket[nThread - 1];
+
+	int step = (int) ceil((float)(max - min) / (float)(nThread-1));
+	bucket[0].min = min;
+	bucket[0].max = min + step;
+	bucket[0].arr = (int*) malloc(sizeof(int) * nElement);
+	bucket[0].n = 0;
+
+	for (i = 1; i < nThread - 1; i++) {
+		bucket[i].min = bucket[i - 1].max + 1;
+       		bucket[i].max = bucket[i].min + step;
+       		bucket[i].arr = (int*) malloc(sizeof(int) * nElement);
+       		bucket[i].n = 0;
+	}
+
+	for (i = 0; i < nElement; i++) {
+		for (j = 0; j < nThread - 1; j++) {
+			if (rand_nums[i] <= bucket[j].max && rand_nums[i] >= bucket[j].min) {
+				pushToBucket(&bucket[j], rand_nums[i]);
+				break;
+			}
+		}
+	}
+
+	#pragma omp parallel for num_threads(nThread)
+	for (i = 0; i < nThread; i++) {
+		sort(bucket[i].arr, bucket[i].n);
+	}
+
+	int* result = (int*) malloc(sizeof(int) * nElement);
+	int nResult = 0;
+
+	for (i = 0; i < nThread; i++) {
+		for (j = 0; j < bucket[i].n; j++) {
+			result[nResult++] = bucket[i].arr[j];
+		}
+	}
+
+	/*for (i = 0; i < nElement; i++) {
+		printf("%d\n", result[i]);
+	}*/
+
+	end = clock();
+    printf("Time Spent: %F\n", (double)(end - begin) / CLOCKS_PER_SEC);
+	
+	return 0;
+}
+