1. package org.jr.util;
  2. /**
  3. * Copyright: Copyright (c) 2002-2004
  4. * Company: JavaResearch(http://www.javaresearch.org)
  5. * 最后更新日期:2003年3月4日
  6. * @author Cherami
  7. */
  8. import org.jr.*;
  9. /**
  10. * 排序工具类,提供常见的需要排序但是又没有实现Comparable接口的类。
  11. * 此类也提供一些创建的排序算法的范例。
  12. * @since 0.5
  13. */
  14. public class CompareUtil {
  15. /**
  16. * 私有构造方法,防止类的实例化,因为工具类不需要实例化。
  17. */
  18. private CompareUtil() {
  19. }
  20. /**
  21. * 比较两个数字。
  22. * 这个方法取Number的double值进行比较,因此只有在两个数严格相等的情况下才返回0,
  23. * 又可能因为Java中Double型和Float的精度不同而导致两个相等的数不返回0。
  24. * @param o1 第一个数字
  25. * @param o2 第二个数字
  26. * @return 第一个数字大于第二个返回1,等于返回0,否则返回-1
  27. * @since 0.5
  28. */
  29. public static int compare(Number o1, Number o2) {
  30. double n1 = o1.doubleValue();
  31. double n2 = o2.doubleValue();
  32. if (n1 < n2) {
  33. return -1;
  34. }
  35. else if (n1 > n2) {
  36. return 1;
  37. }
  38. else {
  39. return 0;
  40. }
  41. }
  42. /**
  43. * 比较两个布尔型值。
  44. * 如果两个的值不同,true被认为等于1,而false等于0。
  45. * @param o1 第一个值
  46. * @param o2 第二个值
  47. * @return 第一个值大于第二个返回1,等于返回0,否则返回-1
  48. * @since 0.5
  49. */
  50. public static int compare(Boolean o1, Boolean o2) {
  51. boolean b1 = o1.booleanValue();
  52. boolean b2 = o2.booleanValue();
  53. if (b1 == b2) {
  54. return 0;
  55. }
  56. else if (b1) {
  57. return 1;
  58. }
  59. else {
  60. return -1;
  61. }
  62. }
  63. /**
  64. * 冒泡排序法排序。
  65. * @param objects 排序对象
  66. * @param isAscent 排序顺序
  67. * @return 排序后应该有的索引数组
  68. * @since 0.5
  69. */
  70. public static int[] n2sort(Comparable[] objects, boolean isAscent) {
  71. int length = objects.length;
  72. int[] indexes = ArrayUtil.getInitedIntArray(length);
  73. for (int i = 0; i < length; i++) {
  74. for (int j = i + 1; j < length; j++) {
  75. if (isAscent == true) {
  76. if (objects[indexes[i]].compareTo(objects[indexes[j]]) > 0) {
  77. swap(indexes, i, j);
  78. }
  79. }
  80. else {
  81. if (objects[indexes[i]].compareTo(objects[indexes[j]]) < 0) {
  82. swap(indexes, i, j);
  83. }
  84. }
  85. }
  86. }
  87. return indexes;
  88. }
  89. /**
  90. * 冒泡排序法排序。
  91. * @param objects 排序对象
  92. * @param key 排序关键字
  93. * @param isAscent 排序顺序
  94. * @return 排序后应该有的索引数组
  95. * @since 0.5
  96. */
  97. public static int[] n2sort(PropertyComparable[] objects, int key,
  98. boolean isAscent) {
  99. int length = objects.length;
  100. int[] indexes = ArrayUtil.getInitedIntArray(length);
  101. for (int i = 0; i < length; i++) {
  102. for (int j = i + 1; j < length; j++) {
  103. if (isAscent == true) {
  104. if (objects[indexes[i]].compareTo(objects[indexes[j]], key) > 0) {
  105. swap(indexes, i, j);
  106. }
  107. }
  108. else {
  109. if (objects[indexes[i]].compareTo(objects[indexes[j]], key) < 0) {
  110. swap(indexes, i, j);
  111. }
  112. }
  113. }
  114. }
  115. return indexes;
  116. }
  117. /**
  118. * 冒泡排序法排序。
  119. * @param objects 排序对象
  120. * @return 按照升序排序后应该有的索引数组
  121. * @since 0.6
  122. */
  123. public static int[] n2sort(Comparable[] objects) {
  124. return n2sort(objects,true);
  125. }
  126. /**
  127. * 冒泡排序法排序。
  128. * @param objects 排序对象
  129. * @param key 排序关键字
  130. * @return 按照升序排序后应该有的索引数组
  131. * @since 0.6
  132. */
  133. public static int[] n2sort(PropertyComparable[] objects, int key) {
  134. return n2sort(objects,key);
  135. }
  136. /**
  137. * 插入排序法排序。
  138. * @param objects 排序对象
  139. * @return 按照升序排序后应该有的索引数组
  140. * @since 0.6
  141. */
  142. public static int[] insertionSort(Comparable[] objects) {
  143. int length = objects.length;
  144. int[] indexes = ArrayUtil.getInitedIntArray(length);
  145. for (int i = 1; i < length; i++) {
  146. int j = i;
  147. Comparable B = objects[indexes[i]];
  148. while ((j > 0) && (objects[indexes[j-1]].compareTo(B) > 0)) {
  149. indexes[j] = indexes[j-1];
  150. j--;
  151. }
  152. indexes[j] = i;
  153. }
  154. return indexes;
  155. }
  156. /**
  157. * 插入排序法排序。
  158. * @param objects 排序对象
  159. * @param key 排序关键字
  160. * @return 按照升序排序后应该有的索引数组
  161. * @since 0.6
  162. */
  163. public static int[] insertionSort(PropertyComparable[] objects, int key) {
  164. int length = objects.length;
  165. int[] indexes = ArrayUtil.getInitedIntArray(length);
  166. for (int i = 1; i < length; i++) {
  167. int j = i;
  168. Comparable B = objects[indexes[i]];
  169. while ((j > 0) && (objects[indexes[j-1]].compareTo(B,key) > 0)) {
  170. indexes[j] = indexes[j-1];
  171. j--;
  172. }
  173. indexes[j] = i;
  174. }
  175. return indexes;
  176. }
  177. /**
  178. * 选择排序法排序。
  179. * @param objects 排序对象
  180. * @return 按照升序排序后应该有的索引数组
  181. * @since 0.6
  182. */
  183. public static int[] selectionSort(Comparable[] objects) {
  184. int length = objects.length;
  185. int[] indexes = ArrayUtil.getInitedIntArray(length);
  186. for (int i = 0; i < length; i++) {
  187. int min = i;
  188. int j;
  189. //在未排序列表里面查找最小元素
  190. for (j = i + 1; j < length; j++) {
  191. if (objects[indexes[j]].compareTo(objects[indexes[min]]) <0 ) {
  192. min = j;
  193. }
  194. }
  195. //将最小的元素交换到未排序元素的最开始
  196. swap(indexes,i,min);
  197. }
  198. return indexes;
  199. }
  200. /**
  201. * 选择排序法排序。
  202. * @param objects 排序对象
  203. * @param key 排序关键字
  204. * @return 按照升序排序后应该有的索引数组
  205. * @since 0.6
  206. */
  207. public static int[] selectionSort(PropertyComparable[] objects, int key) {
  208. int length = objects.length;
  209. int[] indexes = ArrayUtil.getInitedIntArray(length);
  210. for (int i = 0; i < length; i++) {
  211. int min = i;
  212. int j;
  213. //在未排序列表里面查找最小元素
  214. for (j = i + 1; j < length; j++) {
  215. if (objects[indexes[j]].compareTo(objects[indexes[min]],key) <0 ) {
  216. min = j;
  217. }
  218. }
  219. //将最小的元素交换到未排序元素的最开始
  220. swap(indexes,i,min);
  221. }
  222. return indexes;
  223. }
  224. /**
  225. * 双向冒泡排序法排序。
  226. * @param objects 排序对象
  227. * @return 按照升序排序后应该有的索引数组
  228. * @since 0.6
  229. */
  230. public static int[] bidirectionalBubbleSort(Comparable[] objects) {
  231. int length = objects.length;
  232. int[] indexes = ArrayUtil.getInitedIntArray(length);
  233. int j;
  234. int limit = objects.length;
  235. int start = -1;
  236. while (start < limit) {
  237. start++;
  238. limit--;
  239. for (j = start; j < limit; j++) {
  240. if (objects[indexes[j]].compareTo(objects[indexes[j+1]]) > 0) {
  241. swap(indexes,j,j+1);
  242. }
  243. }
  244. for (j = limit; --j >= start;) {
  245. if (objects[indexes[j]].compareTo(objects[indexes[j+1]]) > 0) {
  246. swap(indexes,j,j+1);
  247. }
  248. }
  249. }
  250. return indexes;
  251. }
  252. /**
  253. * 双向冒泡排序法排序。
  254. * @param objects 排序对象
  255. * @param key 排序关键字
  256. * @return 按照升序排序后应该有的索引数组
  257. * @since 0.6
  258. */
  259. public static int[] bidirectionalBubbleSort(PropertyComparable[] objects, int key) {
  260. int length = objects.length;
  261. int[] indexes = ArrayUtil.getInitedIntArray(length);
  262. int j;
  263. int limit = objects.length;
  264. int start = -1;
  265. while (start < limit) {
  266. start++;
  267. limit--;
  268. for (j = start; j < limit; j++) {
  269. if (objects[indexes[j]].compareTo(objects[indexes[j+1]]) > 0) {
  270. swap(indexes,j,j+1);
  271. }
  272. }
  273. for (j = limit; --j >= start;) {
  274. if (objects[indexes[j]].compareTo(objects[indexes[j+1]],key) > 0) {
  275. swap(indexes,j,j+1);
  276. }
  277. }
  278. }
  279. return indexes;
  280. }
  281. /**
  282. * 交换两个元素的值。
  283. * @param indexes 原索引数组
  284. * @param i 第一行
  285. * @param j 第二行
  286. */
  287. private static void swap(int[] indexes, int i, int j) {
  288. int tmp = indexes[i];
  289. indexes[i] = indexes[j];
  290. indexes[j] = tmp;
  291. }
  292. }