From 5c0069d7e9c335fa65d997785f5a8c50f3b02dd5 Mon Sep 17 00:00:00 2001
From: Ahmad Aidin <ahmadaidin08.aa@gmail.com>
Date: Tue, 29 May 2018 14:05:23 +0700
Subject: [PATCH] done

---
 bucketsort.c | 178 ++++++++++++++++++++++++++++++++++++++-------------
 omp_trap.c   |  12 ++--
 test         | Bin 0 -> 17648 bytes
 3 files changed, 140 insertions(+), 50 deletions(-)
 create mode 100644 test

diff --git a/bucketsort.c b/bucketsort.c
index 59e1827..330e20d 100644
--- a/bucketsort.c
+++ b/bucketsort.c
@@ -6,25 +6,33 @@
 #include <time.h>
 #include <assert.h>
 
+typedef struct{
+  int* content;
+  int size;
+  int nContent;
+} Bucket;
+
+typedef struct{
+  Bucket* tables;
+} arrayBucket;
+
+Bucket bucketsort(arrayBucket localArray, int nBucket, int size);
 
-int* bucket(int* localArray, int n, );
-using namespace std;
 int main( int argc, char* argv[] )
 {
-    double start_time, end_time;
-    int i, j, a, b, temp;
-    
+    double start_time, nContent_time;
+
 	if (argc != 2) {
       fprintf(stderr, "usage: %s <number of threads>\n", argv[0]);
       exit(0);
 	}
-	
-	thread_count = strtol(argv[1], NULL, 10);
-	
+
+	int thread_count = strtol(argv[1], NULL, 10);
+
 	int size;
 	scanf("%d", &size);
-	int *array = malloc(sizeof( int) * size);
-	for (i=0;i<size;i++)
+	int *array = (int*)malloc(sizeof( int) * size);
+	for (int i=0;i<size;i++)
 		array[i] = rand() % size;
 
 	// starting time calculation of the sort
@@ -32,28 +40,28 @@ int main( int argc, char* argv[] )
 	// min and max values are got
 	int min = array[0];
 	int max = array[0];
-	for(i=0; i < size; i++) {
-		if(array[i] < min) 
+	for(int i=0; i < size; i++) {
+		if(array[i] < min)
 			min = array[i];
-		if(array[i] > max) 
+		if(array[i] > max)
 			max = array[i];
 	}
-	
+
 	// calculating how many numbers each bucket/process will get numbers
-	int *elementQtyArray = malloc (sizeof(int)*thread_count);
+	int *elementQtyArray = (int*)malloc (sizeof(int)*thread_count);
 	// default values
-	
-	for(int b=1; b < thread_count; b++) {
+
+	for(int b=0; b < thread_count; b++) {
 		elementQtyArray[b] = 0;
 	}
-	
+
 	if(thread_count>1){
 		int boundary1;
 		for(int b=0; b < size; b++) {
 			int increaseOf = max/(thread_count-1);
 			int k = 1;
 			boundary1 = 0;
-			for(j = increaseOf; j <= max; j += increaseOf) {
+			for(int j = increaseOf; j <= max; j += increaseOf) {
 				if(array[b] <= j) {
 					elementQtyArray[k]++;
 					boundary1 = 1;
@@ -65,32 +73,114 @@ int main( int argc, char* argv[] )
 				elementQtyArray[k-1]++;
 		}
 
-		#pragma omp parallel num_threads(thread_count) {
-			
-		}
-	}
- 
-return 0; 
-}
+    Bucket localArray[thread_count];
+    for (int i = 0; i < thread_count; i++) {
+      /* code */
+      localArray[i].size = elementQtyArray[i];
+      localArray[i].content = (int*)malloc (sizeof(int)* localArray[i].size);
+      localArray[i].nContent = 0;
+    }
 
+    int increaseOf = max/(thread_count-1);
+    for(int b=0; b < size; b++) {
+			int k = 1;
+			int boundary1 = 0;
+			for(int j = increaseOf; j <= max; j += increaseOf) {
+				if(array[b] <= j) {
+          int idx=localArray[k].nContent;
+					localArray[k].content[idx]=array[b];
+          localArray[k].nContent++;
+					boundary1 = 1;
+					break;
+				}
+				k++;
+			}
+			if (!boundary1){
+        int idx=localArray[k-1].nContent;
+				localArray[k-1].content[idx]=array[b];
+        localArray[k-1].nContent++;
+      }
+		}/*
+    for(int i=0; i<size; i++){
+      printf("%d ", array[i]);
+    }
+    printf("\n");
+    for(int i=0; i<thread_count; i++){
+      printf("%d ", elementQtyArray[i]);
+    }
+
+    printf("\n");
+    for(int i=0; i<thread_count; i++){
+      for(int j=0; j<localArray[i].size; j++){
+        printf("%d ", localArray[i].content[j]);
+      }
+    }
+    */
+
+
+    arrayBucket localArrayB;
+    localArrayB.tables = localArray;
+
+    Bucket sortenArray;
+
+    sortenArray = bucketsort(localArrayB, thread_count, size);
+
+    printf("\nsortir:\n");
+    for(int x=0; x<size; x++){
+      printf("%d %d\n", array[x], sortenArray.content[x]);
+    }
+
+} else {
 
-int* bucket(int* localArray, int n ){
-	 // --- sorting the bucket
-	int arraytemp[n];
-	
-	int a, b, temp;
-	for (a = 1 ; a <= n - 1; a++) {
-		b = a;
-		while ( b > 0 && localArray[b] < localArray[b-1]) {
-			temp = localArray[b];
-			localArray[b] = localArray[b-1];
-			localArray[b-1] = temp;
-			b--;
-		}
-	}
-	for (a=0; a<n; a++){
-		arraytemp[a] = localArray[a];
-	}
-	return arraytemp;
 }
 
+return 0;
+}
+
+
+Bucket bucketsort(arrayBucket localArrayB, int nBucket,int size){
+  Bucket sortenArray;
+  sortenArray.content= (int*)malloc (sizeof(int)* size);
+  sortenArray.nContent=0;
+  sortenArray.size=size;
+
+
+  int a, b, temp, idx, i, idxAfter;
+  int bucket_num;
+  int my_rank;
+  # pragma omp parallel for schedule(static) default(none) \
+      shared(sortenArray, localArrayB, nBucket) private(my_rank, i,a, b, bucket_num, temp, idx, idxAfter) num_threads(nBucket)
+      for(bucket_num=0; bucket_num<nBucket; bucket_num++){
+        my_rank = omp_get_thread_num();
+        if(bucket_num==my_rank){
+          printf("oke %d %d\n", bucket_num, my_rank);
+          for (a = 1 ; a <localArrayB.tables[bucket_num].size; a++) {
+            b = a;
+            while ( b > 0 && localArrayB.tables[bucket_num].content[b] < localArrayB.tables[bucket_num].content[b-1]) {
+              temp = localArrayB.tables[bucket_num].content[b];
+        			localArrayB.tables[bucket_num].content[b] = localArrayB.tables[bucket_num].content[b-1];
+        			localArrayB.tables[bucket_num].content[b-1] = temp;
+        			b++;
+            }
+      	   }
+          if(bucket_num!=0){
+            idx= localArrayB.tables[bucket_num-1].size;
+          } else {
+            idx=0;
+          }
+
+        idxAfter=idx+localArrayB.tables[bucket_num].size;
+
+        for(a=idx; a<idxAfter; a++){
+          i=0;
+          sortenArray.content[a]=localArrayB.tables[bucket_num].content[i];
+          sortenArray.nContent++;
+          printf("%d %d\n", localArrayB.tables[bucket_num].content[i],sortenArray.content[a]);
+          i++;
+        }
+      }
+    }
+
+  # pragma omp barrier
+  return sortenArray;
+}
diff --git a/omp_trap.c b/omp_trap.c
index c0779f2..94fae60 100644
--- a/omp_trap.c
+++ b/omp_trap.c
@@ -1,7 +1,7 @@
-/* 
+/*
  * Copyrights http://www.cs.usfca.edu/~peter/cs625/code/trap/omp_trap.c
  * File:    omp_trap.c
- * Purpose: Calculate definite integral using trapezoidal 
+ * Purpose: Calculate definite integral using trapezoidal
  *          rule.
  *
  * Input:   a, b, n
@@ -12,7 +12,7 @@
  *    gcc -g -Wall -fopenmp -o omp_trap omp_trap.c
  * Usage:   ./omp_trap <number of threads>
  *
- * Notes:    
+ * Notes:
  * 1.  The function f(x) is hardwired.
  * 2.  This version uses OpenMP's parallel for with variable
  *     scope specified, and static partitioning.
@@ -41,7 +41,7 @@ int main(int argc, char* argv[]) {
 
    printf("Enter a, b, and n\n");
    scanf("%lf %lf %d", &a, &b, &n);
-   
+
    /* OpenMP starts from here */
    integral = Trap(a, b, n);
 
@@ -55,7 +55,7 @@ int main(int argc, char* argv[]) {
 /*------------------------------------------------------------------
  * Function:    Trap
  * Purpose:     Use trapezoidal rule to compute definite integral
- * Input args:  
+ * Input args:
  *    a: left endpoint
  *    b: right endpoint
  *    n: number of trapezoids
@@ -63,7 +63,7 @@ int main(int argc, char* argv[]) {
  */
 double Trap(double a, double b, int n) {
    double  h, x, integral = 0.0;
-   int  i; 
+   int  i;
 
    h = (b-a)/n;
    integral += (f(a) + f(b))/2.0;
diff --git a/test b/test
new file mode 100644
index 0000000000000000000000000000000000000000..0510b595b0934d2b1fcf6f91c7d1f0865be0aa18
GIT binary patch
literal 17648
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
NSHs#e3Ny@M{|h9m>tz4{

literal 0
HcmV?d00001

-- 
GitLab