sorting.c~ 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include "sorting.h"
  5. /*
  6. load specified file
  7. returns array of longs and sets Size
  8. */
  9. long * Load_File(char * Filename, int *Size){
  10. // num ints in file
  11. int val0 = 0;
  12. // open file for reading
  13. FILE * fptr = NULL;
  14. fptr = fopen(Filename, "r");
  15. if (fptr == NULL){ // check for error
  16. printf("File name error.\n");
  17. return NULL;
  18. }
  19. if(fscanf(fptr, "%d", &val0) == 0){ // check for error
  20. printf("File read error.\n");
  21. return NULL;
  22. }
  23. // scan values into buffer (return value)
  24. long *buffer = malloc(sizeof(long) * val0); // malloc return value
  25. if (buffer == NULL){
  26. printf("Buffer malloc error.\n");
  27. return NULL;
  28. }
  29. int i;
  30. for (i = 0; i < val0; i++){
  31. if(fscanf(fptr, "%ld", &buffer[i]) == 0){
  32. printf("File read error.\n");
  33. return NULL; // stop on error
  34. }
  35. }
  36. // clean up
  37. *Size = val0; // assign size
  38. if(!fclose(fptr) == 0){ // close file
  39. printf("File close error.");
  40. return NULL; // return NULL on file close error
  41. }
  42. return buffer;
  43. }
  44. /*
  45. function to save an array of specified size to specified file
  46. returns the number of successful writes (or failure)
  47. */
  48. int Save_File(char *Filename, long *Array, int Size){
  49. // count of successfully written values (return value)
  50. int count = 0;
  51. // write to file
  52. FILE * fptr = NULL;
  53. fptr = fopen(Filename, "w");
  54. if(fprintf(fptr, "%d\n", Size) == 0){
  55. return EXIT_FAILURE;
  56. }
  57. int i;
  58. for(i = 0; i < Size; i++){
  59. fprintf(fptr, "%ld\n", Array[i]);
  60. count++;
  61. }
  62. // close file
  63. if(!fclose(fptr) == 0){
  64. printf("File close error.");
  65. return EXIT_FAILURE; // return NULL on file close error
  66. }
  67. return count;
  68. }
  69. /*
  70. runs Shell insertion sort on Array
  71. counts the number of comparisons and moves (directly involving the array) required to do so
  72. */
  73. void Shell_Insertion_Sort(long *Array, int Size, double *N_Comp, double *N_Move){
  74. // declare and initialize variables
  75. int cCount = 0; // comp count
  76. int mCount = 0; // move count
  77. long temp = 0; // temp value
  78. int * pratt = genSeqOne(Size);
  79. int gapInd = 0; // index to cycle through sequence
  80. int gap = 0; // current gap in loop sequence
  81. int i = 0; // incrementor variable
  82. int j = 0; // incremontor variable
  83. // increment through pratt sequence, starting with largest value
  84. while(pratt[gapInd] > 0){
  85. gap = pratt[gapInd]; // current gap
  86. printf("Using %d as gap size.\n", gap); // print sequence
  87. // insertion sort
  88. for(i = gap; i < Size; i++){
  89. temp = Array[i];
  90. mCount++; // temp = Array[i]
  91. for (j = i; j >= gap && temp < Array[j - gap]; j = j - gap){
  92. cCount++; // temp < Array[j - gap]
  93. Array[j] = Array[j - gap];
  94. mCount++; // Array[j] = Array[j - gap]
  95. }
  96. cCount++; // for loop comparison runs once more than the code it contains
  97. Array[j] = temp;
  98. mCount++; // Array[j] = temp;
  99. }
  100. gapInd++;
  101. }
  102. // clean up
  103. free(pratt); // free resources
  104. *N_Comp = cCount; // set number of comparisons
  105. *N_Move = mCount; // set number of moves
  106. }
  107. /*
  108. use Shell's principle of dividing the array by diminishing gaps with bubble sort on Array
  109. counts the number of comparisons and moves (directly involving the array) required to do so
  110. */
  111. void Improved_Bubble_Sort(long *Array, int Size, double *N_Comp, double *N_Move){
  112. // declare and initialize variables
  113. int cCount = 0; // comparison count
  114. int mCount = 0; // move count
  115. long temp = 0; // temp value
  116. int * sequence = genSeqTwo(Size); // generate sequence
  117. int gapInd = 0; // index to cycle through sequence
  118. int gap = 0; // current gap in loop sequence
  119. int i = 0; // incrementor variable
  120. int j = 0; // incremontor variable
  121. // increment through defined sequence, starting with largest value
  122. while(sequence[gapInd] > 0){
  123. gap = sequence[gapInd]; // current gap
  124. // bubble sort
  125. for(i = gap; i < Size; i++){
  126. for (j = i; j >= gap; j = j - gap){
  127. if(Array[j] < Array[j - gap]){
  128. temp = Array[j];
  129. mCount++; // temp = Array[j]
  130. Array[j] = Array[j - gap];
  131. mCount++; // Array[j] = Array[j - gap]
  132. Array[j - gap] = temp;
  133. mCount++; // Array[j - gap] = temp;
  134. }
  135. cCount++; // Array[j] < Array[j - gap]
  136. }
  137. }
  138. gapInd++;
  139. }
  140. // clean up
  141. free(sequence); // free resources
  142. *N_Comp = cCount; // set number of comparisons
  143. *N_Move = mCount; // set number of moves}
  144. }
  145. /*
  146. generates Sequence 1 up to maxVal
  147. returns an int array ending with 1, with a zero appended at the last index
  148. */
  149. int * genSeqOne(int maxVal){
  150. // variable declarations
  151. int * sequence = calloc(maxVal, sizeof(int));
  152. sequence[0] = 1; // start with one
  153. int i = 0; // incrementor starts on first index
  154. // to keep sequence in proper order
  155. int twoInd = 0; // last index multiplied by two
  156. int threeInd = 0; // last index multiplied by three
  157. // generate values
  158. while(sequence[i] < maxVal) { // don't meet exceed maxVal
  159. i++; // always increment i (always add a value to sequence)
  160. if(sequence[twoInd] * 2 < sequence[threeInd] * 3){
  161. sequence[i] = sequence[twoInd] * 2;
  162. twoInd++; // update two's last index
  163. }
  164. else if(sequence[twoInd] * 2 > sequence[threeInd] * 3){
  165. sequence[i] = sequence[threeInd] * 3;
  166. threeInd++; // update three's last index
  167. }
  168. else{ // if sequence[twoInd] * 2 == sequence[threeInd] * 3
  169. sequence[i] = sequence[twoInd] * 2;
  170. twoInd++; // update last index
  171. threeInd++; // of both values
  172. }
  173. }
  174. sequence[i] = 0; // exceded maxVal on last pass, clean that up
  175. // reverse the generated values
  176. int * reverse = calloc(i + 1, sizeof(int)); // last value is 0
  177. i--; // move to penultimate index of sequence
  178. int j = 0; // start at first index of reverse
  179. while(sequence[i] != 1){ // stop at first value (sequence[0] = 1)
  180. reverse[j] = sequence[i];
  181. j++;
  182. i--;
  183. }
  184. reverse[j] = 1; // penultimate value is 1
  185. // clean up
  186. free(sequence); // free inital sequence
  187. return reverse; // return reversed sequence (smaller)
  188. }
  189. /*
  190. generates Sequence 2 based on n
  191. returns an int array ending with 1, with a zero appended at the last index
  192. */
  193. int * genSeqTwo(int n){
  194. // initalize
  195. int * sequence = calloc(n, sizeof(int)); // large array
  196. sequence[0] = n / 1.3; // set first value
  197. int i = 1; // set second index first
  198. while(sequence[i - 1] > 1){ // stop if n is one or two
  199. sequence[i] = sequence[i - 1] / 1.3; // value set based on last index
  200. if(sequence[i] == 9 || sequence[i] == 10){
  201. sequence[i] = 11;
  202. }
  203. i++;
  204. }
  205. // make smaller array
  206. int * smaller = calloc(i + 1, sizeof(int));
  207. int j = 0;
  208. while(sequence[j] != 0){
  209. smaller[j] = sequence[j];
  210. j++;
  211. }
  212. free(sequence);
  213. return smaller;
  214. }
  215. /*
  216. writes Sequence 1 to Filename
  217. the largest value in the sequence will be less than N
  218. */
  219. void Save_Seq1(char *Filename, int N){
  220. // generate sequence
  221. int * sequence = genSeqOne(N);
  222. // open file for writing
  223. FILE * fptr = NULL;
  224. fptr = fopen(Filename, "w");
  225. // print values to file
  226. int i = 0;
  227. while(sequence[i] > 0){
  228. fprintf(fptr, "%d\n", sequence[i]);
  229. i++;
  230. }
  231. // clean up
  232. if(!fclose(fptr) == 0){ // close file
  233. printf("File close error.");
  234. }
  235. free(sequence); // release memory
  236. }
  237. /*
  238. writes Sequence 1 to Filename
  239. the sequence is based on integers of N/1.3^index
  240. */
  241. void Save_Seq2(char *Filename, int N){
  242. // generate sequence
  243. int * sequence = genSeqTwo(N);
  244. // open file for writing
  245. FILE * fptr = NULL;
  246. fptr = fopen(Filename, "w");
  247. // print values to file
  248. int i = 0;
  249. while(sequence[i] > 0){
  250. fprintf(fptr, "%d\n", sequence[i]);
  251. i++;
  252. }
  253. // clean up
  254. if(!fclose(fptr) == 0){ // close file
  255. printf("File close error.");
  256. }
  257. free(sequence); // release memory
  258. }