main.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <limits>
  5. #include <math.h>
  6. #include <iomanip>
  7. #include <chrono>
  8. #include <algorithm>
  9. using namespace std;
  10. const int k = 4;
  11. struct Clock
  12. {
  13. Clock (){
  14. start_time = chrono::high_resolution_clock::now();
  15. }
  16. float get_info(){
  17. chrono::duration<float> seconds = chrono::high_resolution_clock::now() - start_time;
  18. return seconds.count();
  19. }
  20. chrono::high_resolution_clock::time_point start_time;
  21. };
  22. unsigned int counter = 0;
  23. void KWayMerge(vector<int> &numArr, vector<int> &helperArr, int kPartitions, int low, int high){
  24. int totalSize = high - low + 1;
  25. int sizePartitions = max(totalSize / kPartitions, 1);
  26. int sizeLastPartition = totalSize - sizePartitions * (kPartitions - 1);
  27. if (totalSize < kPartitions)
  28. {
  29. KWayMerge(numArr,helperArr,totalSize, low, high);
  30. return;
  31. }
  32. vector<int> indices(kPartitions);
  33. int count = low;
  34. int min;
  35. int minPosition;
  36. int currentPart;
  37. while (count <= high){
  38. min = numeric_limits<int>::max();
  39. minPosition = 0;
  40. currentPart = low;
  41. for (int i = 0; i < kPartitions; i++){
  42. if (i == kPartitions - 1 && indices[i] == sizeLastPartition){
  43. break;
  44. }
  45. if (indices[i] == sizePartitions && i != kPartitions - 1){
  46. currentPart += sizePartitions;
  47. continue;
  48. }
  49. counter++;
  50. if (helperArr[currentPart + indices[i]] < min){
  51. min = helperArr[currentPart + (indices[i])];
  52. minPosition = i;
  53. }
  54. currentPart += sizePartitions;
  55. }
  56. numArr[count++] = min;
  57. indices[minPosition]++;
  58. }
  59. for (int i = low; i <= high; i++){
  60. //counter++;
  61. helperArr[i] = numArr[i];
  62. }
  63. }
  64. void KWayMergeSort(vector<int> &numArr, vector<int> &helperArr, int kPartitions, int startPart, int endPart){
  65. int totalSize = endPart - startPart + 1;
  66. int sizePartitions = max(totalSize / kPartitions, 1);
  67. int sizeEndPartition = totalSize - (sizePartitions * (kPartitions - 1));
  68. if (sizePartitions > 1){
  69. for (int i = 0; i < kPartitions; i++){
  70. int newEndPart;
  71. if (i == kPartitions - 1){
  72. newEndPart = i * sizePartitions + startPart + sizeEndPartition - 1;
  73. }
  74. else{
  75. newEndPart = i * sizePartitions + startPart + sizePartitions - 1;
  76. }
  77. KWayMergeSort(numArr,helperArr,kPartitions, i * sizePartitions + startPart, newEndPart);
  78. }
  79. }
  80. else{
  81. if (sizeEndPartition > 1){
  82. KWayMergeSort(numArr,helperArr,kPartitions, endPart - sizeEndPartition, endPart);
  83. }
  84. }
  85. KWayMerge(numArr,helperArr,kPartitions, startPart, endPart);
  86. }
  87. void sort(vector<int> &numArr, vector<int> &helperArr, int kPartitions){
  88. counter = 0;
  89. helperArr = vector<int>(numArr.size());
  90. for (int i = 0; i < numArr.size(); i++)
  91. {
  92. helperArr[i] = numArr[i];
  93. }
  94. KWayMergeSort(numArr,helperArr,kPartitions, 0, numArr.size() - 1);
  95. }
  96. void fill_arr(vector<int> &arr, long int size){
  97. for (unsigned int var = 0; var < size; ++var)
  98. arr.at(var) = rand();
  99. }
  100. void fill_arr_keyboard(vector<int> &arr, int size){
  101. for (int var = 0; var < size; ++var)
  102. cin>>arr[var];
  103. }
  104. void show_arr(vector<int> arr, long int size){
  105. for (int i = 0;i < size; ++i)
  106. cout<<arr[i]<<" ";
  107. cout<<endl;
  108. }
  109. double log(double a, double b)
  110. {
  111. return log(b) / log(a);
  112. }
  113. void ShowRes(vector<int> &numArr){
  114. Clock timer; vector<int> helperArr; const unsigned int N = numArr.size(); const double analitical = N*log(k,N);
  115. sort(numArr,helperArr,k);
  116. //counter = (int)analitical-N/7;
  117. float timeRes = timer.get_info();
  118. cout<<"| "<<setw(10)<<N<<" | "<<setw(10)<<fixed<<setprecision(5)<<timeRes<<" | "<<setw(10)<<counter<<" | "<<setprecision(2)<<setw(10)<<analitical<<" | "<<setw(10)<<counter*1.0/analitical<<" |"<<endl;
  119. }
  120. vector<int> do_research_best(vector<int>& numArr, vector<int>& helperArr){
  121. sort(numArr,helperArr,k);
  122. return numArr;
  123. }
  124. vector<int> do_research_middle( vector<int>& numArr, vector<int>&){
  125. return numArr;
  126. }
  127. vector<int> do_research_worst(vector<int>& numArr, vector<int>& helperArr){
  128. sort(numArr,helperArr,k);
  129. reverse(numArr.begin(), numArr.end());
  130. return numArr;
  131. }
  132. void research(vector<int> action(vector<int>&, vector<int>&)){
  133. cout<<"------------------------------------------------------------------"<<endl;
  134. cout<<"| size time T(e) T(a) T(e)/T(a) |"<<endl;
  135. cout<<"------------------------------------------------------------------"<<endl;
  136. for (unsigned int i = 10000;i<=50000;i+=10000){
  137. vector<int> numArr(i); vector<int> helperArr;
  138. fill_arr(numArr,i);
  139. numArr = action(numArr, helperArr);
  140. ShowRes(numArr);
  141. }
  142. cout<<"------------------------------------------------------------------"<<endl;
  143. }
  144. int main()
  145. {
  146. cout<<"Enter 1 for test."<<endl<<"Enter 2 for research."<<endl;
  147. string cmd;cin>>cmd; vector<int> helperArr;
  148. if (cmd == "1"){
  149. vector<int> numArr(8);
  150. fill_arr_keyboard(numArr,8);
  151. sort(numArr,helperArr,k);
  152. cout<<"Sorted array: "<<endl;
  153. show_arr(numArr,8);
  154. }
  155. if (cmd == "2"){
  156. cout<<"4-way Merge Sort"<<endl;
  157. cout<<"For best case:"<<endl;
  158. research(do_research_best);
  159. cout<<"For random case:"<<endl;
  160. research(do_research_middle);
  161. cout<<"For worst case:"<<endl;
  162. research(do_research_worst);
  163. }
  164. return 0;
  165. }