sort.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*******************************************************************************
  2. License:
  3. This software and/or related materials was developed at the National Institute
  4. of Standards and Technology (NIST) by employees of the Federal Government
  5. in the course of their official duties. Pursuant to title 17 Section 105
  6. of the United States Code, this software is not subject to copyright
  7. protection and is in the public domain.
  8. This software and/or related materials have been determined to be not subject
  9. to the EAR (see Part 734.3 of the EAR for exact details) because it is
  10. a publicly available technology and software, and is freely distributed
  11. to any interested party with no licensing requirements. Therefore, it is
  12. permissible to distribute this software as a free download from the internet.
  13. Disclaimer:
  14. This software and/or related materials was developed to promote biometric
  15. standards and biometric technology testing for the Federal Government
  16. in accordance with the USA PATRIOT Act and the Enhanced Border Security
  17. and Visa Entry Reform Act. Specific hardware and software products identified
  18. in this software were used in order to perform the software development.
  19. In no case does such identification imply recommendation or endorsement
  20. by the National Institute of Standards and Technology, nor does it imply that
  21. the products and equipment identified are necessarily the best available
  22. for the purpose.
  23. This software and/or related materials are provided "AS-IS" without warranty
  24. of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
  25. NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
  26. or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
  27. licensed product, however used. In no event shall NIST be liable for any
  28. damages and/or costs, including but not limited to incidental or consequential
  29. damages of any kind, including economic damage or injury to property and lost
  30. profits, regardless of whether NIST shall be advised, have reason to know,
  31. or in fact shall know of the possibility.
  32. By using this software, you agree to bear all risk relating to quality,
  33. use and performance of the software and/or related materials. You agree
  34. to hold the Government harmless from any claim arising from your use
  35. of the software.
  36. *******************************************************************************/
  37. /***********************************************************************
  38. LIBRARY: LFS - NIST Latent Fingerprint System
  39. FILE: SORT.C
  40. AUTHOR: Michael D. Garris
  41. DATE: 03/16/1999
  42. UPDATED: 03/16/2005 by MDG
  43. Contains sorting routines required by the NIST Latent Fingerprint
  44. System (LFS).
  45. ***********************************************************************
  46. ROUTINES:
  47. sort_indices_int_inc()
  48. sort_indices_double_inc()
  49. bubble_sort_int_inc_2()
  50. bubble_sort_double_inc_2()
  51. bubble_sort_double_dec_2()
  52. bubble_sort_int_inc()
  53. ***********************************************************************/
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include "lfs.h"
  57. /*************************************************************************
  58. **************************************************************************
  59. #cat: sort_indices_int_inc - Takes a list of integers and returns a list of
  60. #cat: indices referencing the integer list in increasing order.
  61. #cat: The original list of integers is also returned in sorted
  62. #cat: order.
  63. Input:
  64. ranks - list of integers to be sorted
  65. num - number of integers in the list
  66. Output:
  67. optr - list of indices referencing the integer list in sorted order
  68. ranks - list of integers in increasing order
  69. Return Code:
  70. Zero - successful completion
  71. Negative - system error
  72. **************************************************************************/
  73. int sort_indices_int_inc(int **optr, int *ranks, const int num)
  74. {
  75. int *order;
  76. int i;
  77. /* Allocate list of sequential indices. */
  78. order = (int *)malloc(num * sizeof(int));
  79. if(order == (int *)NULL){
  80. fprintf(stderr, "ERROR : sort_indices_int_inc : malloc : order\n");
  81. return(-390);
  82. }
  83. /* Initialize list of sequential indices. */
  84. for(i = 0; i < num; i++)
  85. order[i] = i;
  86. /* Sort the indecies into rank order. */
  87. bubble_sort_int_inc_2(ranks, order, num);
  88. /* Set output pointer to the resulting order of sorted indices. */
  89. *optr = order;
  90. /* Return normally. */
  91. return(0);
  92. }
  93. /*************************************************************************
  94. **************************************************************************
  95. #cat: sort_indices_double_inc - Takes a list of doubles and returns a list of
  96. #cat: indices referencing the double list in increasing order.
  97. #cat: The original list of doubles is also returned in sorted
  98. #cat: order.
  99. Input:
  100. ranks - list of doubles to be sorted
  101. num - number of doubles in the list
  102. Output:
  103. optr - list of indices referencing the double list in sorted order
  104. ranks - list of doubles in increasing order
  105. Return Code:
  106. Zero - successful completion
  107. Negative - system error
  108. **************************************************************************/
  109. int sort_indices_double_inc(int **optr, double *ranks, const int num)
  110. {
  111. int *order;
  112. int i;
  113. /* Allocate list of sequential indices. */
  114. order = (int *)malloc(num * sizeof(int));
  115. if(order == (int *)NULL){
  116. fprintf(stderr, "ERROR : sort_indices_double_inc : malloc : order\n");
  117. return(-400);
  118. }
  119. /* Initialize list of sequential indices. */
  120. for(i = 0; i < num; i++)
  121. order[i] = i;
  122. /* Sort the indicies into rank order. */
  123. bubble_sort_double_inc_2(ranks, order, num);
  124. /* Set output pointer to the resulting order of sorted indices. */
  125. *optr = order;
  126. /* Return normally. */
  127. return(0);
  128. }
  129. /*************************************************************************
  130. **************************************************************************
  131. #cat: bubble_sort_int_inc_2 - Takes a list of integer ranks and a corresponding
  132. #cat: list of integer attributes, and sorts the ranks
  133. #cat: into increasing order moving the attributes
  134. #cat: correspondingly.
  135. Input:
  136. ranks - list of integers to be sort on
  137. items - list of corresponding integer attributes
  138. len - number of items in list
  139. Output:
  140. ranks - list of integers sorted in increasing order
  141. items - list of attributes in corresponding sorted order
  142. **************************************************************************/
  143. void bubble_sort_int_inc_2(int *ranks, int *items, const int len)
  144. {
  145. int done = 0;
  146. int i, p, n, trank, titem;
  147. /* Set counter to the length of the list being sorted. */
  148. n = len;
  149. /* While swaps in order continue to occur from the */
  150. /* previous iteration... */
  151. while(!done){
  152. /* Reset the done flag to TRUE. */
  153. done = TRUE;
  154. /* Foreach rank in list up to current end index... */
  155. /* ("p" points to current rank and "i" points to the next rank.) */
  156. for (i=1, p = 0; i<n; i++, p++){
  157. /* If previous rank is < current rank ... */
  158. if(ranks[p] > ranks[i]){
  159. /* Swap ranks. */
  160. trank = ranks[i];
  161. ranks[i] = ranks[p];
  162. ranks[p] = trank;
  163. /* Swap items. */
  164. titem = items[i];
  165. items[i] = items[p];
  166. items[p] = titem;
  167. /* Changes were made, so set done flag to FALSE. */
  168. done = FALSE;
  169. }
  170. /* Otherwise, rank pair is in order, so continue. */
  171. }
  172. /* Decrement the ending index. */
  173. n--;
  174. }
  175. }
  176. /*************************************************************************
  177. **************************************************************************
  178. #cat: bubble_sort_double_inc_2 - Takes a list of double ranks and a
  179. #cat: corresponding list of integer attributes, and sorts the
  180. #cat: ranks into increasing order moving the attributes
  181. #cat: correspondingly.
  182. Input:
  183. ranks - list of double to be sort on
  184. items - list of corresponding integer attributes
  185. len - number of items in list
  186. Output:
  187. ranks - list of doubles sorted in increasing order
  188. items - list of attributes in corresponding sorted order
  189. **************************************************************************/
  190. void bubble_sort_double_inc_2(double *ranks, int *items, const int len)
  191. {
  192. int done = 0;
  193. int i, p, n, titem;
  194. double trank;
  195. /* Set counter to the length of the list being sorted. */
  196. n = len;
  197. /* While swaps in order continue to occur from the */
  198. /* previous iteration... */
  199. while(!done){
  200. /* Reset the done flag to TRUE. */
  201. done = TRUE;
  202. /* Foreach rank in list up to current end index... */
  203. /* ("p" points to current rank and "i" points to the next rank.) */
  204. for (i=1, p = 0; i<n; i++, p++){
  205. /* If previous rank is < current rank ... */
  206. if(ranks[p] > ranks[i]){
  207. /* Swap ranks. */
  208. trank = ranks[i];
  209. ranks[i] = ranks[p];
  210. ranks[p] = trank;
  211. /* Swap items. */
  212. titem = items[i];
  213. items[i] = items[p];
  214. items[p] = titem;
  215. /* Changes were made, so set done flag to FALSE. */
  216. done = FALSE;
  217. }
  218. /* Otherwise, rank pair is in order, so continue. */
  219. }
  220. /* Decrement the ending index. */
  221. n--;
  222. }
  223. }
  224. /***************************************************************************
  225. **************************************************************************
  226. #cat: bubble_sort_double_dec_2 - Conducts a simple bubble sort returning a list
  227. #cat: of ranks in decreasing order and their associated items in sorted
  228. #cat: order as well.
  229. Input:
  230. ranks - list of values to be sorted
  231. items - list of items, each corresponding to a particular rank value
  232. len - length of the lists to be sorted
  233. Output:
  234. ranks - list of values sorted in descending order
  235. items - list of items in the corresponding sorted order of the ranks.
  236. If these items are indices, upon return, they may be used as
  237. indirect addresses reflecting the sorted order of the ranks.
  238. ****************************************************************************/
  239. void bubble_sort_double_dec_2(double *ranks, int *items, const int len)
  240. {
  241. int done = 0;
  242. int i, p, n, titem;
  243. double trank;
  244. n = len;
  245. while(!done){
  246. done = 1;
  247. for (i=1, p = 0;i<n;i++, p++){
  248. /* If previous rank is < current rank ... */
  249. if(ranks[p] < ranks[i]){
  250. /* Swap ranks */
  251. trank = ranks[i];
  252. ranks[i] = ranks[p];
  253. ranks[p] = trank;
  254. /* Swap corresponding items */
  255. titem = items[i];
  256. items[i] = items[p];
  257. items[p] = titem;
  258. done = 0;
  259. }
  260. }
  261. n--;
  262. }
  263. }
  264. /*************************************************************************
  265. **************************************************************************
  266. #cat: bubble_sort_int_inc - Takes a list of integers and sorts them into
  267. #cat: increasing order using a simple bubble sort.
  268. Input:
  269. ranks - list of integers to be sort on
  270. len - number of items in list
  271. Output:
  272. ranks - list of integers sorted in increasing order
  273. **************************************************************************/
  274. void bubble_sort_int_inc(int *ranks, const int len)
  275. {
  276. int done = 0;
  277. int i, p, n;
  278. int trank;
  279. /* Set counter to the length of the list being sorted. */
  280. n = len;
  281. /* While swaps in order continue to occur from the */
  282. /* previous iteration... */
  283. while(!done){
  284. /* Reset the done flag to TRUE. */
  285. done = TRUE;
  286. /* Foreach rank in list up to current end index... */
  287. /* ("p" points to current rank and "i" points to the next rank.) */
  288. for (i=1, p = 0; i<n; i++, p++){
  289. /* If previous rank is < current rank ... */
  290. if(ranks[p] > ranks[i]){
  291. /* Swap ranks. */
  292. trank = ranks[i];
  293. ranks[i] = ranks[p];
  294. ranks[p] = trank;
  295. /* Changes were made, so set done flag to FALSE. */
  296. done = FALSE;
  297. }
  298. /* Otherwise, rank pair is in order, so continue. */
  299. }
  300. /* Decrement the ending index. */
  301. n--;
  302. }
  303. }