常用排序java版.docx
《常用排序java版.docx》由会员分享,可在线阅读,更多相关《常用排序java版.docx(42页珍藏版)》请在冰豆网上搜索。
常用排序java版
这篇排序文章从思想理解到实现,然后到整理,花了我几天的时间,现把它记录于此,希望对大家有一定的帮助,写的不好的请不要见笑,写错了的,请指出来我更正。
最后如果对你有一定的帮助,请回贴支持一下哦^_^!
申明:
排序算法思想来自互联网,代码自己实现,仅供参考。
∙插入排序
直接插入排序、希尔排序
∙选择排序
简单选择排序、堆排序
∙交换排序
冒泡排序、快速排序
∙归并排序
∙基数排序
排序基类
Java代码
1.package sort;
2.
3.import java.util.Arrays;
4.import java.util.Comparator;
5.import java.util.Random;
6.
7./**
8. * 排序接口,所有的排序算法都要继承该抽象类,并且要求数组中的
9. * 元素要具有比较能力,即数组元素已实现了Comparable接口
10. *
11. * @author jzj
12. * @date 2009-12-5
13. *
14. * @param
15. */
16.public abstract class Sort> {
17.
18. public final Comparator DEFAULT_ORDER = new DefaultComparator();
19. public final Comparator REVERSE_ORDER = new ReverseComparator();
20.
21. /**
22. * 排序算法,需实现,对数组中指定的元素进行排序
23. * @param array 待排序数组
24. * @param from 从哪里
25. * @param end 排到哪里
26. * @param c
27. */
28. public abstract void sort(E[] array, int from, int end, Comparator c);
29.
30. /**
31. * 对数组中指定部分进行排序
32. * @param from 从哪里
33. * @param len 排到哪里
34. * @param array 待排序数组
35. * @param c 比较器
36. */
37. public void sort(int from, int len, E[] array, Comparator c) {
38. sort(array, 0, array.length - 1, c);
39. }
40.
41. /**
42. * 对整个数组进行排序,可以使用自己的排序比较器,也可使用该类提供的两个比较器
43. * @param array 待排序数组
44. * @param c 比较器
45. */
46. public final void sort(E[] array, Comparator c) {
47. sort(0, array.length, array, c);
48. }
49.
50. /**
51. * 对整个数组进行排序,采用默认排序比较器
52. * @param array 待排序数组
53. */
54. public final void sort(E[] array) {
55. sort(0, array.length, array, this.DEFAULT_ORDER);
56. }
57.
58. //默认比较器(一般为升序,但是否真真是升序还得看E是怎样实现Comparable接口的)
59. private class DefaultComparator implements Comparator {
60. public int compare(E o1, E o2) {
61. return pareTo(o2);
62. }
63. }
64.
65. //反序比较器,排序刚好与默认比较器相反
66. private class ReverseComparator implements Comparator {
67. public int compare(E o1, E o2) {
68. return pareTo(o1);
69. }
70. }
71.
72. /**
73. * 交换数组中的两个元素的位置
74. * @param array 待交换的数组
75. * @param i 第一个元素
76. * @param j 第二个元素
77. */
78. protected final void swap(E[] array, int i, int j) {
79. if (i !
= j) {//只有不是同一位置时才需交换
80. E tmp = array[i];
81. array[i] = array[j];
82. array[j] = tmp;
83. }
84. }
85.
86. /**
87. * 数组元素后移
88. * @param array 待移动的数组
89. * @param startIndex 从哪个开始移
90. * @param endIndex 到哪个元素止
91. */
92. protected final void move(E[] array, int startIndex, int endIndex) {
93. for (int i = endIndex; i >= startIndex; i--) {
94. array[i + 1] = array[i];
95. }
96. }
97.
98. /**
99. * 以指定的步长将数组元素后移,步长指定每个元素间的间隔
100. * @param array 待排序数组
101. * @param startIndex 从哪里开始移
102. * @param endIndex 到哪个元素止
103. * @param step 步长
104. */
105. protected final void move(E[] array, int startIndex, int endIndex, int step) {
106. for (int i = endIndex; i >= startIndex; i -= step) {
107. array[i + step] = array[i];
108. }
109. }
110.
111. //测试方法
112. @SuppressWarnings("unchecked")
113. public static final > void testSort(Sort sorter, E[] array) {
114.
115. if (array == null) {
116. array = randomArray();
117. }
118. //为了第二次排序,需拷贝一份
119. E[] tmpArr = (E[]) new Comparable[array.length];
120. System.arraycopy(array, 0, tmpArr, 0, array.length);
121.
122. System.out.println("源 - " + Arrays.toString(tmpArr));
123.
124. sorter.sort(array, sorter.REVERSE_ORDER);
125. System.out.println("降 - " + Arrays.toString(array));
126.
127. sorter.sort(tmpArr, sorter.DEFAULT_ORDER);
128. System.out.println("升 - " + Arrays.toString(tmpArr));
129. }
130.
131. //生成随机数组
132. @SuppressWarnings("unchecked")
133. private static > E[] randomArray() {
134. Random r = new Random(System.currentTimeMillis());
135. Integer[] a = new Integer[r.nextInt(30)];
136. for (int i = 0; i < a.length; i++) {
137. a[i] = new Integer(r.nextInt(100));
138. }
139. return (E[]) a;
140. }
141.}
packagesort;
importjava.util.Arrays;
importjava.util.Comparator;
importjava.util.Random;
/**
*排序接口,所有的排序算法都要继承该抽象类,并且要求数组中的
*元素要具有比较能力,即数组元素已实现了Comparable接口
*
*@authorjzj
*@date2009-12-5
*
*@param
*/
publicabstractclassSort>{
publicfinalComparatorDEFAULT_ORDER=newDefaultComparator();
publicfinalComparatorREVERSE_ORDER=newReverseComparator();
/**
*排序算法,需实现,对数组中指定的元素进行排序
*@paramarray待排序数组
*@paramfrom从哪里
*@paramend排到哪里
*@paramc
*/
publicabstractvoidsort(E[]array,intfrom,intend,Comparatorc);
/**
*对数组中指定部分进行排序
*@paramfrom从哪里
*@paramlen排到哪里
*@paramarray待排序数组
*@paramc比较器
*/
publicvoidsort(intfrom,intlen,E[]array,Comparatorc){
sort(array,0,array.length-1,c);
}
/**
*对整个数组进行排序,可以使用自己的排序比较器,也可使用该类提供的两个比较器
*@paramarray待排序数组
*@paramc比较器
*/
publicfinalvoidsort(E[]array,Comparatorc){
sort(0,array.length,array,c);
}
/**
*对整个数组进行排序,采用默认排序比较器
*@paramarray待排序数组
*/
publicfinalvoidsort(E[]array){
sort(0,array.length,array,this.DEFAULT_ORDER);
}
//默认比较器(一般为升序,但是否真真是升序还得看E是怎样实现Comparable接口的)
privateclassDefaultComparatorimplementsComparator{
publicintcompare(Eo1,Eo2){
returnpareTo(o2);
}
}
//反序比较器,排序刚好与默认比较器相反
privateclassReverseComparatorimplementsComparator{
publicintcompare(Eo1,Eo2){
returnpareTo(o1);
}
}
/**
*交换数组中的两个元素的位置
*@paramarray待交换的数组
*@parami第一个元素
*@paramj第二个元素
*/
protectedfinalvoidswap(E[]array,inti,intj){
if(i!
=j){//只有不是同一位置时才需交换
Etmp=array[i];
array[i]=array[j];
array[j]=tmp;
}
}
/**
*数组元素后移
*@paramarray待移动的数组
*@paramstartIndex从哪个开始移
*@paramendIndex到哪个元素止
*/
protectedfinalvoidmove(E[]array,intstartIndex,intendIndex){
for(inti=endIndex;i>=startIndex;i--){
array[i+1]=array[i];
}
}
/**
*以指定的步长将数组元素后移,步长指定每个元素间的间隔
*@paramarray待排序数组
*@paramstartIndex从哪里开始移
*@paramendIndex到哪个元素止
*@paramstep步长
*/
protectedfinalvoidmove(E[]array,intstartIndex,intendIndex,intstep){
for(inti=endIndex;i>=startIndex;i-=step){
array[i+step]=array[i];
}
}
//测试方法
@SuppressWarnings("unchecked")
publicstaticfinal>voidtestSort(Sortsorter,E[]array){
if(array==null){
array=randomArray();
}
//为了第二次排序,需拷贝一份
E[]tmpArr=(E[])newComparable[array.length];
System.arraycopy(array,0,tmpArr,0,array.length);
System.out.println("源-"+Arrays.toString(tmpArr));
sorter.sort(array,sorter.REVERSE_ORDER);
System.out.println("降-"+Arrays.toString(array));
sorter.sort(tmpArr,sorter.DEFAULT_ORDER);
System.out.println("升-"+Arrays.toString(tmpArr));
}
//生成随机数组
@SuppressWarnings("unchecked")
privatestatic>E[]randomArray(){
Randomr=newRandom(System.currentTimeMillis());
Integer[]a=newInteger[r.nextInt(30)];
for(inti=0;ia[i]=newInteger(r.nextInt(100));
}
return(E[])a;
}
}
插入排序
直接插入排序
一般直接插入排序的时间复杂度为O(n^2),但是当数列基本有序时,如果按照有数列顺序排时,时间复杂度将改善到O(n),另外,因直接插入排序算法简单,如果待排序列规模不很大时效率也较高。
在已经排好序的序列中查找待插入的元素的插入位置,并将待插入元素插入到有序列表中的过程。
将数组分成两部分,初始化时,前部分数组为只有第一个元素,用来存储已排序元素,我们这里叫arr1;后部分数组的元素为除第一个元素的所有元素,为待排序或待插入元素,我们这里叫arr2。
排序时使用二层循环:
第一层对arr2进行循环,每次取后部分数组(待排序数组)里的第一个元素(我们称为待排序元素或称待插入元素)e1,然后在第二层循环中对arr1(已排好序的数组)从第一个元素往后进行循环,查到第一个大于待插入元素(如果是升序排列)或第一个小于待插入元素(如果是降序排列)e2,然后对arr1从e2元素开始往后的所有元素向后移,最后把e1插入到原来e2所在的位置。
这样反复地对arr2进行循环,直到arr2中所有的待插入的元素都插入到arr1中。
Java代码
1.package sort;
2.
3.import java.util.Comparator;
4.
5./**
6. * 直接插入排序算法
7. * @author jzj
8. * @date 2009-12-5
9. *
10. * @param
11. */
12.public class InsertSort> extends Sort {
13.
14. /**
15. * 排序算法的实现,对数组中指定的元素进行排序
16. * @param array 待排序的数组
17. * @param from 从哪里开始排序
18. * @param end 排到哪里
19. * @param c 比较器
20. */
21. public void sort(E[] array, int from, int end, Comparator c) {
22.
23. /*
24. * 第一层循环:
对待插入(排序)的元素进行循环
25. * 从待排序数组断的第二个元素开始循环,到最后一个元素(包括)止
26. */
27. for (int i = from + 1; i <= end; i++) {
28. /*
29. * 第二层循环:
对有序数组进行循环,且从有序数组最第一个元素开始向后循环
30. * 找到第一个大于待插入的元素
31. * 有序数组初始元素只有一个,且为源数组的第一个元素,一个元素数组总是有序的
32. */
33. for (int j = 0; j < i; j++) {
34. E insertedElem = array[i];//待插入到有序数组的元素
35. //从有序数组中最一个元素开始查找第一个大于待插入的元素
36. if (pare(array[j], insertedElem) > 0) {
37. //找到插入点后,从插入点开始向后