void myQuickSort(vector<int>& nums, int left, int right) { if (left < right) { int pivot = partition(nums, left, right); myQuickSort(nums, left, pivot-1); myQuickSort(nums, pivot+1, right); } }
void myQuickSort(std::vector < T > &myVec, int q, int r, const int switchThresh) { T pivot; int i, j; /* done with this part of the vector? -> exit function */ if (q >= r) return; /* is the partition to be processed smaller than a certain threshhold? * -> then use insertion sort and exit function afterwards */ if (r - q < switchThresh) { myInsertSort(myVec, q, r); return; } /* now actually sort our partition */ /* choose pivot, initialize borders */ pivot = myVec[r]; i = q - 1; j = r; /* partition step, which moves smaller numbers to the left * and larger numbers to the right of the pivot */ while (true) { while (myVec[++i] < pivot); while (myVec[--j] > pivot); if (i >= j) break; std::swap(myVec[i], myVec[j]); } std::swap(myVec[i], myVec[r]); /* recursively call yourself with new subpartitions, * i is index of pivot * each recursive function call is marked as a task, making parallel * processing of them possible. * note that this is only possible, because all partitions can be * processed independently of each other. */ # pragma intel omp taskq { # pragma intel omp task { myQuickSort(myVec, q, i - 1, switchThresh); } # pragma intel omp task { myQuickSort(myVec, i + 1, r, switchThresh); } } }
node* myQuickSort(node *list) { int pivot, i; node *less = NULL, *greater = NULL, *temp; if (size(list) <= 1) { return list; } pivot = (get(list, 0) + get(list, (size(list) - 1))) / 2; temp = list; i = 0; while (temp) { if (get(list, i) > pivot) { greater = add(greater, get(list, i)); } else { less = add(less, get(list, i)); } temp = temp->next; i++; } /*printf("pivot: %d\n", pivot); //printf("less:\n"); //printList(less); //printf("greater:\n"); //printList(greater); //printf("end\n"); */ freeList(list); return concatList( (myQuickSort(less)), (myQuickSort(greater)) ); }
node *quickSortMain(node *list) { /*unsorted*/ printList(list); printf("-999\n"); /*sort plz*/ list = myQuickSort(list); /*sorted*/ printList(list); printf("-999\n"); /*sort plz*/ list = myQuickSort(list); /*sorted*/ printList(list); printf("-999\n"); return list; }
/** main function with initialization, command line argument parsing, * memory allocation, OpenMP setup, wall--clock time measurement. */ int main(int argc, char *argv[]) { std::vector < int >myVec; int numThreads; int numEntries; int switchThresh; char *PARAM_NAMES[NUM_ARGS] = {"Number of integer to sort:", "Number of threads:", "SwitchThresh:"}; char *TIMERS_NAMES[NUM_TIMERS] = {"Total_time" }; char *DEFAULT_VALUES[NUM_ARGS] = {"10000000", "1", "1000"}; /* used for time measurements */ double accTime; numThreads = omp_get_max_threads(); OSCR_init (numThreads, "QuickSort", "", NUM_ARGS, PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES, argc, argv); numEntries = OSCR_getarg_int(1); numThreads = OSCR_getarg_int(2); switchThresh = OSCR_getarg_int(3); /* and run with the specified number of threads */ omp_set_num_threads(numThreads); /* initialize random number generator to fixed seed. this is done, so * that every run of the algorithm is sorting the exact same vector. * this way, we can compare runs easily */ //std::srand( std::time(0) ); std::srand(123); /* Reserve sufficient capacity for vector once and for all */ myVec.reserve(myVec.size() + numEntries); /* fill the vector with random numbers */ for (int i = 0; i < numEntries; ++i) { myVec.push_back(std::rand()); } /* Start measuring the time */ OSCR_timer_start(0); /* sort vector in parallel */ # pragma omp parallel shared (myVec, switchThresh, numThreads) { # pragma intel omp taskq { # pragma intel omp task { myQuickSort(myVec, 0, myVec.size() - 1, switchThresh); } } } /* Finish time measurement */ OSCR_timer_stop(0); /* calculate elapsed time */ accTime = OSCR_timer_read(0); /* determine and print out, whether or not the vector was sorted ok */ if (vectorValidate(myVec)) std::cout << "\nSuccess, wall-clock time: " << accTime << "\n\n"; else std::cout << "\nSorting FAILED!" << "\n\n"; OSCR_report(); return 0; }
/** main function with initialization, command line argument parsing, * memory allocation, OpenMP setup, wall--clock time measurement. */ int main(int argc, char *argv[]) { std::vector < int >myVec; std::stack < std::pair < int, int > >globalTodoStack; int numThreads; int numEntries; int switchThresh; char *PARAM_NAMES[NUM_ARGS] = {(char *)"Number of integer to sort:", (char *)"Number of threads:", (char *)"SwitchThresh:"}; char *TIMERS_NAMES[NUM_TIMERS] = {(char *)"Total_time" }; char *DEFAULT_VALUES[NUM_ARGS] = {(char *)"100", (char *)"2", (char *)"10"}; /* this number indicates, how many threads are doing useful work atm. */ int numBusyThreads = 1; /* used for time measurements */ double accTime; /* used for performance measurements */ std::vector < int >globalStackWrite; numThreads = omp_get_max_threads(); OSCR_init (numThreads, (char *)"QuickSort", (char *)"", NUM_ARGS, PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES, argc, argv); numEntries = OSCR_getarg_int(1); numThreads = OSCR_getarg_int(2); switchThresh = OSCR_getarg_int(3); /* initialize the performance measures */ for (int i = 0; i < numThreads; ++i) { globalStackWrite.push_back(0); } /* and run with the specified number of threads */ omp_set_num_threads(numThreads); /* initialize random number generator to fixed seed. this is done, so * that every run of the algorithm is sorting the exact same vector. * this way, we can compare runs easily */ //std::srand( std::time(0) ); std::srand(123); /* Reserve sufficient capacity for vector once and for all */ myVec.reserve(myVec.size() + numEntries); /* fill the vector with random numbers */ for (int i = 0; i < numEntries; ++i) { myVec.push_back(std::rand()); } /* Start measuring the time */ OSCR_timer_start(0); /* sort vector in parallel */ # pragma omp parallel shared(myVec, globalTodoStack, numThreads, \ switchThresh, numBusyThreads, globalStackWrite) { /* start sorting with only one thread, the others wait for the stack * to fill up */ if (0 == omp_get_thread_num()) { myQuickSort(myVec, 0, myVec.size() - 1, switchThresh, globalTodoStack, numBusyThreads, numThreads, globalStackWrite); } else { myQuickSort(myVec, 0, 0, switchThresh, globalTodoStack, numBusyThreads, numThreads, globalStackWrite); } } /* Finish time measurement */ OSCR_timer_stop(0); /* calculate elapsed time */ accTime = OSCR_timer_read(0); /* determine and print out, whether or not the vector was sorted ok */ if (vectorValidate(myVec)) std::cout << "\nSuccess, wall-clock time: " << accTime << "\n\n"; else std::cout << "\nSorting FAILED!" << "\n\n"; int globalStackWriteSum = 0; /* sum up and print out all performance measures */ for (int i = 0; i < numThreads; ++i) { globalStackWriteSum += globalStackWrite[i]; std::cout << i << ".: gSW: " << globalStackWrite[i] << "\n"; } std::cout << std:: endl << "Total: gSW: " << globalStackWriteSum << "\n\n"; OSCR_report(); return 0; }
int findKthLargest(vector<int>& nums, int k) { myQuickSort(nums, 0, nums.size()-1); return nums[nums.size()-k]; }