sorting.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. // insertion sort
  87. for(i = gap; i < Size; i++){
  88. temp = Array[i];
  89. mCount++; // temp = Array[i]
  90. for (j = i; j >= gap && temp < Array[j - gap]; j = j - gap){
  91. cCount++; // temp < Array[j - gap]
  92. Array[j] = Array[j - gap];
  93. mCount++; // Array[j] = Array[j - gap]
  94. }
  95. cCount++; // for loop comparison runs once more than the code it contains
  96. Array[j] = temp;
  97. mCount++; // Array[j] = temp;
  98. }
  99. gapInd++;
  100. }
  101. // clean up
  102. free(pratt); // free resources
  103. *N_Comp = cCount; // set number of comparisons
  104. *N_Move = mCount; // set number of moves
  105. }
  106. /*
  107. use Shell's principle of dividing the array by diminishing gaps with bubble sort on Array
  108. counts the number of comparisons and moves (directly involving the array) required to do so
  109. */
  110. void Improved_Bubble_Sort(long *Array, int Size, double *N_Comp, double *N_Move){
  111. // declare and initialize variables
  112. int cCount = 0; // comparison count
  113. int mCount = 0; // move count
  114. long temp = 0; // temp value
  115. int * sequence = genSeqTwo(Size); // generate sequence
  116. int gapInd = 0; // index to cycle through sequence
  117. int gap = 0; // current gap in loop sequence
  118. int i = 0; // incrementor variable
  119. int j = 0; // incremontor variable
  120. // increment through defined sequence, starting with largest value
  121. while(sequence[gapInd] > 0){
  122. gap = sequence[gapInd]; // current gap
  123. // bubble sort
  124. for(i = gap; i < Size; i++){
  125. for (j = i; j >= gap; j = j - gap){
  126. if(Array[j] < Array[j - gap]){
  127. temp = Array[j];
  128. mCount++; // temp = Array[j]
  129. Array[j] = Array[j - gap];
  130. mCount++; // Array[j] = Array[j - gap]
  131. Array[j - gap] = temp;
  132. mCount++; // Array[j - gap] = temp;
  133. }
  134. cCount++; // Array[j] < Array[j - gap]
  135. }
  136. }
  137. gapInd++;
  138. }
  139. // clean up
  140. free(sequence); // free resources
  141. *N_Comp = cCount; // set number of comparisons
  142. *N_Move = mCount; // set number of moves}
  143. }
  144. /*
  145. generates Sequence 1 up to maxVal
  146. returns an int array ending with 1, with a zero appended at the last index
  147. */
  148. int * genSeqOne(int maxVal){
  149. // variable declarations
  150. int * sequence = calloc(maxVal, sizeof(int));
  151. sequence[0] = 1; // start with one
  152. int i = 0; // incrementor starts on first index
  153. // to keep sequence in proper order
  154. int twoInd = 0; // last index multiplied by two
  155. int threeInd = 0; // last index multiplied by three
  156. // generate values
  157. while(sequence[i] < maxVal) { // don't meet exceed maxVal
  158. i++; // always increment i (always add a value to sequence)
  159. if(sequence[twoInd] * 2 < sequence[threeInd] * 3){
  160. sequence[i] = sequence[twoInd] * 2;
  161. twoInd++; // update two's last index
  162. }
  163. else if(sequence[twoInd] * 2 > sequence[threeInd] * 3){
  164. sequence[i] = sequence[threeInd] * 3;
  165. threeInd++; // update three's last index
  166. }
  167. else{ // if sequence[twoInd] * 2 == sequence[threeInd] * 3
  168. sequence[i] = sequence[twoInd] * 2;
  169. twoInd++; // update last index
  170. threeInd++; // of both values
  171. }
  172. }
  173. sequence[i] = 0; // exceded maxVal on last pass, clean that up
  174. // reverse the generated values
  175. int * reverse = calloc(i + 1, sizeof(int)); // last value is 0
  176. i--; // move to penultimate index of sequence
  177. int j = 0; // start at first index of reverse
  178. while(sequence[i] != 1){ // stop at first value (sequence[0] = 1)
  179. reverse[j] = sequence[i];
  180. j++;
  181. i--;
  182. }
  183. reverse[j] = 1; // penultimate value is 1
  184. // clean up
  185. free(sequence); // free inital sequence
  186. return reverse; // return reversed sequence (smaller)
  187. }
  188. /*
  189. generates Sequence 2 based on n
  190. returns an int array ending with 1, with a zero appended at the last index
  191. */
  192. int * genSeqTwo(int n){
  193. // initalize
  194. int * sequence = calloc(n, sizeof(int)); // large array
  195. sequence[0] = n / 1.3; // set first value
  196. int i = 1; // set second index first
  197. while(sequence[i - 1] > 1){ // stop if n is one or two
  198. sequence[i] = sequence[i - 1] / 1.3; // value set based on last index
  199. if(sequence[i] == 9 || sequence[i] == 10){
  200. sequence[i] = 11;
  201. }
  202. i++;
  203. }
  204. // make smaller array
  205. int * smaller = calloc(i + 1, sizeof(int));
  206. int j = 0;
  207. while(sequence[j] != 0){
  208. smaller[j] = sequence[j];
  209. j++;
  210. }
  211. free(sequence);
  212. return smaller;
  213. }
  214. /*
  215. writes Sequence 1 to Filename
  216. the largest value in the sequence will be less than N
  217. */
  218. void Save_Seq1(char *Filename, int N){
  219. // generate sequence
  220. int * sequence = genSeqOne(N);
  221. // open file for writing
  222. FILE * fptr = NULL;
  223. fptr = fopen(Filename, "w");
  224. // print values to file
  225. int i = 0;
  226. while(sequence[i] > 0){
  227. fprintf(fptr, "%d\n", sequence[i]);
  228. i++;
  229. }
  230. // clean up
  231. if(!fclose(fptr) == 0){ // close file
  232. printf("File close error.");
  233. }
  234. free(sequence); // release memory
  235. }
  236. /*
  237. writes Sequence 1 to Filename
  238. the sequence is based on integers of N/1.3^index
  239. */
  240. void Save_Seq2(char *Filename, int N){
  241. // generate sequence
  242. int * sequence = genSeqTwo(N);
  243. // open file for writing
  244. FILE * fptr = NULL;
  245. fptr = fopen(Filename, "w");
  246. // print values to file
  247. int i = 0;
  248. while(sequence[i] > 0){
  249. fprintf(fptr, "%d\n", sequence[i]);
  250. i++;
  251. }
  252. // clean up
  253. if(!fclose(fptr) == 0){ // close file
  254. printf("File close error.");
  255. }
  256. free(sequence); // release memory
  257. }