diff --git a/src/Coba.c b/src/Coba.c
deleted file mode 100644
index 3a98195636abc7846703dfeae6c84e819b317312..0000000000000000000000000000000000000000
--- a/src/Coba.c
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <mpi.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-// Menuliskan array ke layar
-void PrintArray(int T[], int a, int b)
-{
-    for (int i = a; i <= b - 1; i++)
-    {
-        printf("%d ", T[i - 1]);
-    }
-    printf("%d\n", T[b - 1]);
-}
-
-// Melakukan partisi sembari menukar value dengan pivot ke-i
-void Partisi(int T[], int i, int j, int *k)
-{
-    int pivot = T[i - 1];
-    int p = i;
-    int q = j;
-    while (p <= q)
-    {
-        while (T[p - 1] < pivot)
-        {
-            p++;
-        }
-        while (T[q - 1] > pivot)
-        {
-            q--;
-        }
-        if (p < q)
-        {
-            int temp = T[p - 1];
-            T[p - 1] = T[q - 1];
-            T[q - 1] = temp;
-            p++;
-            q--;
-        }
-        else if (p == q)
-        {
-            p++;
-        }
-    }
-    *k = q;
-}
-
-// Mengurutkan array dengan menggunakan Quick Sort
-void SequentialQuickSort(int T[], int i, int j)
-{
-    int k;
-    if (i < j)
-    {
-        Partisi(T, i, j, &k);
-        SequentialQuickSort(T, i, k);
-        SequentialQuickSort(T, k + 1, j);
-    }
-}
-
-int main()
-{
-    int my_rank, comm_sz, n;
-    int T[5000];
-    int N;
-
-    MPI_Init(NULL, NULL);
-    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
-    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
-
-    if (my_rank == 0){
-        scanf("%d", &N);
-        for (int i = 0; i < N; i++)
-        {
-            scanf("%d", &T[i]);
-        }
-        printf("Hello World");
-        double t = MPI_Wtime();
-        // QuickSort(T, 1, N);
-        // MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
-        // MPI_Bcast(&T, 5000, MPI_INT, 0, MPI_COMM_WORLD);
-        MPI_Send(&T, 5000, MPI_INT, 0, 0, MPI_COMM_WORLD);
-        printf("Hello World");
-        t = MPI_Wtime() - t;
-        printf("Waktu Eksekusi: %.4f ms\n", t / CLOCKS_PER_SEC * 1000);
-        
-    } else {
-        // MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
-        // MPI_Bcast(&T, 5000, MPI_INT, 0, MPI_COMM_WORLD);
-        MPI_Recv(&T, 5000, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-        // printf("Process %d: After MPI_Bcast, value is %d\n", my_rank, N);
-    }
-
-    PrintArray(T, 1, N);
-    return 0;
-}
\ No newline at end of file
diff --git a/src/Graph_Generator.c b/src/Graph_Generator.c
index d9916904861c277f62f55e84bd51ce194977cf81..4b38cb20a5acd2cd687505ccc0e51828ad37d553 100644
--- a/src/Graph_Generator.c
+++ b/src/Graph_Generator.c
@@ -28,7 +28,7 @@ int main(){
             }
 
             else{
-                int r = rand() % 20;
+                int r = rand() % (2*N);
                 int val = (r == 5) || (r == 0) || (r < 3) ? -1: r;
                 edge[i][j] = val;
                 edge[j][i] = val;
diff --git a/src/Hello b/src/Hello
new file mode 100755
index 0000000000000000000000000000000000000000..db07b316b3fa565c722217df5f338b3cfef62373
Binary files /dev/null and b/src/Hello differ
diff --git a/src/MPI_Communication.c b/src/MPI_Communication.c
deleted file mode 100644
index 70dc805455f1901f9aa25133fd66326a73c97e4c..0000000000000000000000000000000000000000
--- a/src/MPI_Communication.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <mpi.h>
-#include <stdio.h>
-
-int main()
-{
-    int id, size, x;
-
-    MPI_Init(NULL, NULL);
-    MPI_Comm_size(MPI_COMM_WORLD, &size);
-    MPI_Comm_rank(MPI_COMM_WORLD, &id);
-
-    // P0 mengirim pesan x ke P1
-    // P1 menerima pesan dari P0, disimpan ke x
-    if (id == 0) {
-        x = 6;
-        MPI_Send(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
-    }
-    if (id == 1)
-        MPI_Recv(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, NULL);
-
-    printf("P[%d] x: %d\n", id, x);
-
-    MPI_Finalize();
-    return 0;
-}
\ No newline at end of file
diff --git a/src/MST_OpenMPI b/src/MST_OpenMPI
index b930a6e530331da0962716a45935f44a7cc369b1..28e6b1e49e20808b13c387ea4ea2a9e1fed5fb50 100755
Binary files a/src/MST_OpenMPI and b/src/MST_OpenMPI differ
diff --git a/src/MST_OpenMPI.c b/src/MST_OpenMPI.c
index 1fe81b8b60fb46c107cb71ac094e85ef3bc79adc..e1883e5df04236dbe4c8c7a28b020ee026a638c9 100644
--- a/src/MST_OpenMPI.c
+++ b/src/MST_OpenMPI.c
@@ -7,6 +7,7 @@
 #include <string.h>
 #include <time.h>
 #include <mpi.h>
+#include <stddef.h>
 
 // Edge structure
 typedef struct
@@ -31,7 +32,6 @@ void makeStruct(MPI_Datatype *mpi_edge_type)
 
     //Inisialisasi
     MPI_Datatype types[3] = {MPI_INT, MPI_INT, MPI_INT};
-    MPI_Datatype mpi_edge_type;
     MPI_Aint offset[3];
     int block[3] = {1,1,1};
 
@@ -200,6 +200,96 @@ void bubbleSort(Edge arr[], int n, int type)
             }
 }
 
+int pow2(int x){
+    return 2 << x; 
+}
+
+// Menuliskan array ke layar
+void PrintArray(Edge arr[], int a, int b)
+{
+    for (int i = a; i <= b - 1; i++)
+    {
+        printf("%d ", arr[i - 1].weight);
+    }
+    printf("%d\n", arr[b - 1].weight);
+}
+
+// Melakukan partisi sembari menukar value dengan pivot ke-i
+void Partisi(Edge arr[], int i, int j, int *k)
+{
+    int pivot = arr[i - 1].weight;
+    int p = i;
+    int q = j;
+    while (p <= q)
+    {
+        while (arr[p - 1].weight < pivot)
+        {
+            p++;
+        }
+        while (arr[q - 1].weight > pivot)
+        {
+            q--;
+        }
+        if (p < q)
+        {
+            Edge temp = arr[p - 1];
+            arr[p - 1] = arr[q - 1];
+            arr[q - 1] = temp;
+            p++;
+            q--;
+        }
+        else if (p == q)
+        {
+            p++;
+        }
+    }
+    *k = q;
+}
+
+// Mengurutkan array dengan menggunakan Quick Sort versi Sequential
+void SequentialQuickSort(Edge arr[], int i, int j)
+{
+    int k;
+    if (i < j)
+    {
+        Partisi(arr, i, j, &k);
+        SequentialQuickSort(arr, i, k);
+        SequentialQuickSort(arr, k + 1, j);
+    }
+}
+
+// Mengurutkan array dengan metode Quick Sort Parallel
+void QuickSort(Edge arr[], int i, int j, int rank, int max_rank, int rank_index){
+    MPI_Datatype mpi_edge_type;
+    makeStruct(&mpi_edge_type);
+
+    int distributed_process = rank + pow2(rank_index);
+    rank_index++;
+
+    // If the rank of distributed process is higher than max rank
+    if (distributed_process > max_rank) {
+        SequentialQuickSort(arr, i, j);
+    }
+    else {
+        int pivot;
+        Partisi(arr, i, j, &pivot);
+
+        // Upper half of array is larger than lower half of array
+        if (pivot-i > j-pivot-1){
+            MPI_Send(&arr[pivot + 1], j - pivot - 1, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD);
+			QuickSort(arr, i, pivot, rank, max_rank, rank_index + 1);
+			MPI_Recv(&arr[pivot + 1], j - pivot - 1, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+            printf("rank x : %d\n", rank);
+        } else {
+			MPI_Send(&arr[i], pivot - i, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD);
+			QuickSort(arr, pivot + 1, j, rank, max_rank, rank_index + 1);
+			MPI_Recv(&arr[i], pivot - i, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+            printf("rank y : %d\n", rank);
+        }
+    }
+}
+
+
 /// Create graph based from the adjacency matrix in file
 Graph *ReadArguments()
 {
@@ -207,6 +297,7 @@ Graph *ReadArguments()
 
     int V, weight;
     scanf("%d", &V);
+    // V = 5;
     graph->V = V;
     graph->edge = (Edge *)(malloc(((V * V - V) / 2) * sizeof(Edge)));
 
@@ -217,6 +308,8 @@ Graph *ReadArguments()
         for (int j = 0; j < V; j++)
         {
             scanf("%d", &weight);
+            // int r = rand() % (2* V);
+            // int weight = (r < 0.2 * V) ? -1: r;
             if ((weight != -1) && (i <= j))
             {
                 graph->edge[E].src = i;
@@ -298,31 +391,32 @@ int compare_src(const void *a, const void *b)
 
 
 
-void PreQuickSort (Edge result[], int size, int rank) {
-    if (rank==0) {
+void PreQuickSort (Edge result[], int resultLength, int size, int rank) {
+    // if (rank==0) {
         //Implementasi quicksort disini
+    QuickSort(result, 1, resultLength, rank, size, 0);
         
-    } else {
-        MPI_Datatype mpi_edge_type;
-        makeStruct(&mpi_edge_type);
+    // } else {
+    //     MPI_Datatype mpi_edge_type;
+    //     makeStruct(&mpi_edge_type);
         
-        int idxcnt = 0;
-        Edge arr;
-        MPI_Status status;
-        while (rank >= pow(2, idxcnt)) {
-            idxcnt = idxcnt+1;
-        }
-
-        int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
-        source = MPI_Get_count(&status, mpi_edge_type, &arr);
-        int src = status.MPI_SOURCE;
-
-        Edge * temp = (Edge *) malloc (sizeof(Edge) *arr);
-        source = MPI_Recv(temp, arr, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
-        //Impementasiquicksort disini
-        source = MPI_Send(temp, arr, mpi_edge_type, src, 1, MPI_COMM_WORLD);
-        free(temp);
-    }
+    //     int idxcnt = 0;
+    //     int arrLength;
+    //     MPI_Status status;
+    //     while (rank >= pow2(idxcnt)) {
+    //         idxcnt = idxcnt+1;
+    //     }
+
+    //     int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
+    //     source = MPI_Get_count(&status, mpi_edge_type, &arrLength);
+    //     int src = status.MPI_SOURCE;
+
+    //     Edge* temp = (Edge *) malloc (sizeof(Edge) *arrLength);
+    //     source = MPI_Recv(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+    //     QuickSort(temp, 0, arrLength, rank, size, idxcnt);
+    //     source = MPI_Send(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD);
+    //     free(temp);
+    // }
 
 }
 
@@ -337,9 +431,9 @@ void KruskalMST(Graph *graph, Edge result[], int *e, int size, int rank)
     // Step 1: Sort all the edges into correspendent sorted edges
     // bubbleSort(graph->edge, graph->E, 1);
     // QuickSortWeight(graph->edge, 0, graph->E, size, rank);
-
-
-
+    // printf("Process %d\n", rank);
+    PreQuickSort(graph->edge, graph->E, size, rank);
+    // PrintArray(graph->edge, 0, graph->E-1);
     // Step 2: Allocate memory for creating V subsets
     Subset *subsets = CreateSubset(V);
 
@@ -357,6 +451,8 @@ void KruskalMST(Graph *graph, Edge result[], int *e, int size, int rank)
     }
 
     // QuickSortSrc(graph->edge, 0, graph->E, size, rank);
+    // QuickSortSrc(result, 1, (*e));
+    qsort(result, *e, sizeof(result[0]), compare_src);
     return;
 }
 
@@ -391,15 +487,43 @@ int main()
     int rank;
     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
+    if (rank == 0){
+        Graph *graph= ReadArguments();
+        Edge result[graph->V];
+        int e = 0;
+        double t = MPI_Wtime();
+        KruskalMST(graph, result, &e, size, rank);
+        t = MPI_Wtime() - t;
+        printResult(result, e);
+        printf("Waktu Eksekusi: %f ms \n", (t * 1000));
+        MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
+        
+ 
+    } else {
+        // printf("Process %d\n", rank);
+        MPI_Datatype mpi_edge_type;
+        makeStruct(&mpi_edge_type);
+        
+        int idxcnt = 0;
+        int arrLength;
+        MPI_Status status;
+        while (rank >= pow2(idxcnt)) {
+            idxcnt = idxcnt+1;
+        }
+
+        int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
+        source = MPI_Get_count(&status, mpi_edge_type, &arrLength);
+        int src = status.MPI_SOURCE;
+        // arrLength = 100;
 
-    Graph *graph= ReadArguments();
-    Edge result[graph->V];
-    int e = 0;
-    int t = clock();
-    KruskalMST(graph, result, &e, size, rank);
-    t = clock() - t;
-    printResult(result, e);
-    printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000);
+        Edge* temp = (Edge *) malloc (sizeof(Edge) *arrLength);
+        source = MPI_Recv(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+        QuickSort(temp, 0, arrLength, rank, size, idxcnt);
+        source = MPI_Send(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD);
+        // printf("Process %d\n", rank);
+        free(temp);
+    }
     MPI_Finalize();
+    
     return 0;
 }
\ No newline at end of file
diff --git a/src/QuickSort b/src/QuickSort
deleted file mode 100755
index 6fbff9dbcbc9d1eb9659fdac8069c2176f7e8825..0000000000000000000000000000000000000000
Binary files a/src/QuickSort and /dev/null differ
diff --git a/src/QuickSort_MPI b/src/QuickSort_MPI
new file mode 100755
index 0000000000000000000000000000000000000000..503e03f92f00f3015ebb70649b3c5dde037d456a
Binary files /dev/null and b/src/QuickSort_MPI differ
diff --git a/src/QuickSort_MPI.c b/src/QuickSort_MPI.c
new file mode 100644
index 0000000000000000000000000000000000000000..a61d268f3470969986c99eefaf9f37e2ce21725a
--- /dev/null
+++ b/src/QuickSort_MPI.c
@@ -0,0 +1,145 @@
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+
+int pow2(int x){
+    return 2 << x; 
+}
+
+// Menuliskan array ke layar
+void PrintArray(int T[], int a, int b)
+{
+    for (int i = a; i <= b - 1; i++)
+    {
+        printf("%d ", T[i - 1]);
+    }
+    printf("%d\n", T[b - 1]);
+}
+
+// Melakukan partisi sembari menukar value dengan pivot ke-i
+void Partisi(int T[], int i, int j, int *k)
+{
+    int pivot = T[i - 1];
+    int p = i;
+    int q = j;
+    while (p <= q)
+    {
+        while (T[p - 1] < pivot)
+        {
+            p++;
+        }
+        while (T[q - 1] > pivot)
+        {
+            q--;
+        }
+        if (p < q)
+        {
+            int temp = T[p - 1];
+            T[p - 1] = T[q - 1];
+            T[q - 1] = temp;
+            p++;
+            q--;
+        }
+        else if (p == q)
+        {
+            p++;
+        }
+    }
+    *k = q;
+}
+
+// Mengurutkan array dengan menggunakan Quick Sort versi Sequential
+void SequentialQuickSort(int T[], int i, int j)
+{
+    int k;
+    if (i < j)
+    {
+        Partisi(T, i, j, &k);
+        SequentialQuickSort(T, i, k);
+        SequentialQuickSort(T, k + 1, j);
+    }
+}
+
+// Mengurutkan array dengan metode Quick Sort Parallel
+void QuickSort(int T[], int i, int j, int rank, int max_rank, int rank_index){
+    int distributed_process = rank + pow2(rank_index);
+    rank_index++;
+
+    // If the rank of distributed process is higher than max rank
+    if (distributed_process > max_rank) {
+        SequentialQuickSort(T, i, j);
+    }
+    else {
+        int pivot;
+        Partisi(T, i, j, &pivot);
+
+        // Upper half of array is larger than lower half of array
+        if (pivot-i > j-pivot-1){
+            MPI_Send(&T[pivot + 1], j - pivot - 1, MPI_INT, distributed_process, 1, MPI_COMM_WORLD);
+			QuickSort(T, i, pivot, rank, max_rank, rank_index + 1);
+			MPI_Recv(&T[pivot + 1], j - pivot - 1, MPI_INT, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+		} else {
+			MPI_Send(&T[i], pivot - i, MPI_INT, distributed_process, 1, MPI_COMM_WORLD);
+			QuickSort(T, pivot + 1, j, rank, max_rank, rank_index + 1);
+			MPI_Recv(&T[i], pivot - i, MPI_INT, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+        }
+    }
+}
+
+int main()
+{
+    int rank, size, n;
+    int T[5000];
+    int N;
+
+    // OpenMPI Environment Initialization
+    MPI_Init(NULL, NULL);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+    // If the root process is in charge
+    if (rank == 0){
+
+        // Get adjacency matrix input from user
+        scanf("%d", &N);
+        for (int i = 0; i < N; i++)
+        {
+            scanf("%d", &T[i]);
+        }
+
+        // Calculate execution time
+        double t = MPI_Wtime();
+        QuickSort(T, 1, N, rank, size, 0);
+        t = MPI_Wtime() - t;
+        printf("Waktu Eksekusi: %.4f ms\n", t / CLOCKS_PER_SEC * 1000);
+        PrintArray(T, 1, N);
+
+    // Process with rank > 0    
+    } else {        
+        int idxcnt = 0;
+        int N;
+        MPI_Status status;
+        while (rank >= pow2(idxcnt)) {
+            idxcnt = idxcnt+1;
+        }
+
+        int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
+        source = MPI_Get_count(&status, MPI_INT, &N);
+        int src = status.MPI_SOURCE;
+
+        int* temp = (int*) malloc (sizeof(int) * N);
+        source = MPI_Recv(temp, N, MPI_INT, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+        QuickSort(temp, 0, N, rank, size, idxcnt);
+        source = MPI_Send(temp, N, MPI_INT, src, 1, MPI_COMM_WORLD);
+        free(temp);
+    }
+
+    MPI_Barrier(MPI_COMM_WORLD);
+    printf("Hello World %d\n\n", rank);
+    MPI_Finalize();
+
+    return 0;
+}
\ No newline at end of file
diff --git a/src/QuickSort_Serial b/src/QuickSort_Serial
new file mode 100755
index 0000000000000000000000000000000000000000..284c1c2d1e324723214f69f9732fd39956c0fba6
Binary files /dev/null and b/src/QuickSort_Serial differ
diff --git a/src/QuickSort_Serial.c b/src/QuickSort_Serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..b9ff71ae339759f0a1aa533789f64b58eeb8c87b
--- /dev/null
+++ b/src/QuickSort_Serial.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+// Menuliskan array ke layar
+void PrintArray(int T[], int a, int b)
+{
+    for (int i = a; i <= b - 1; i++)
+    {
+        printf("%d ", T[i - 1]);
+    }
+    printf("%d\n", T[b - 1]);
+}
+
+// Melakukan partisi sembari menukar value dengan pivot ke-i
+void Partisi(int T[], int i, int j, int *k)
+{
+    int pivot = T[i - 1];
+    int p = i;
+    int q = j;
+    while (p <= q)
+    {
+        while (T[p - 1] < pivot)
+        {
+            p++;
+        }
+        while (T[q - 1] > pivot)
+        {
+            q--;
+        }
+        if (p < q)
+        {
+            int temp = T[p - 1];
+            T[p - 1] = T[q - 1];
+            T[q - 1] = temp;
+            p++;
+            q--;
+        }
+        else if (p == q)
+        {
+            p++;
+        }
+    }
+    *k = q;
+}
+
+// Mengurutkan array dengan menggunakan Quick Sort
+void QuickSort(int T[], int i, int j)
+{
+    
+    int k;
+    if (i < j)
+    {
+        Partisi(T, i, j, &k);
+        QuickSort(T, i, k);
+        QuickSort(T, k + 1, j);
+    }
+}
+
+int main()
+{
+    int T[5000];
+    int N;
+    scanf("%d", &N);
+    for (int i = 0; i < N; i++)
+    {
+        scanf("%d", &T[i]);
+    }
+
+    PrintArray(T, 1, N);
+    float t = clock();
+    QuickSort(T, 1, N);
+    t = clock() - t;
+    printf("Waktu Eksekusi: %f ms\n", (t / CLOCKS_PER_SEC) * 1000);
+    return 0;
+}
\ No newline at end of file
diff --git a/src/a.out b/src/a.out
new file mode 100755
index 0000000000000000000000000000000000000000..c025e37d329922d797f1eb508f8b6361f8e36884
Binary files /dev/null and b/src/a.out differ
diff --git a/src/b.out b/src/b.out
new file mode 100755
index 0000000000000000000000000000000000000000..242962d277a94b229fa5945ad3f7db3743b75f51
Binary files /dev/null and b/src/b.out differ
diff --git a/src/c.out b/src/c.out
new file mode 100755
index 0000000000000000000000000000000000000000..fe49bd9526854d08142ec62c9dc90cdb8d94b197
Binary files /dev/null and b/src/c.out differ
diff --git a/src/log b/src/log
new file mode 100644
index 0000000000000000000000000000000000000000..b20862adaba836b0e0e52e8f5b4aab971e28b9da
Binary files /dev/null and b/src/log differ