2022年常用排序算法分析与实现 .pdf
《2022年常用排序算法分析与实现 .pdf》由会员分享,可在线阅读,更多相关《2022年常用排序算法分析与实现 .pdf(22页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、这篇排序文章从思想理解 到实现,然后到整理,花了我几天的时间,现把它记录于此,希望对大家有一定的帮助,写的不好的请不要见笑,写错了的,请指出来我更正。最后如果对你有一定的帮助,请回贴支持一下哦 _ !申明: 排序算法思想来自互联网,代码自己实现,仅供参考。插入排序直接插入排序、希尔排序选择排序简单选择排序、堆排序交换排序冒泡排序、快速排序归并排序基数排序排序基类Java 代码1. package sort; 2.3. import java.util.Arrays; 4. import java.util.Comparator; 名师资料总结 - - -精品资料欢迎下载 - - - - - -
2、 - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 22 页 - - - - - - - - - 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 SortE extends Comparabl
3、e 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 a
4、rray, 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. * 对整个数组进行排序,可以使用自己的排序
5、比较器,也可使用该类提供的两个比较器43. * param array 待排序数组名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 22 页 - - - - - - - - - 44. * param c 比较器45. */ 46. public final void sort(E array, Comparator c) 47. sort(0, array.length, array, c); 48. 49. 50. /* 51. * 对整个数组进行排序,采用默认排序比较
6、器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. 6
7、3. 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, i
8、nt j) 79. if (i != j) /只有不是同一位置时才需交换80. E tmp = arrayi; 81. arrayi = arrayj; 82. arrayj = tmp; 83. 84. 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 22 页 - - - - - - - - - 85. 86. /* 87. * 数组元素后移88. * param array 待移动的数组89. * param startIndex 从哪个开始移90. * param
9、endIndex 到哪个元素止91. */ 92. protected final void move(E array, int startIndex, int endIndex) 93. for (int i = endIndex; i = startIndex; i-) 94. arrayi + 1 = arrayi; 95. 96. 97. 98. /* 99. * 以指定的步长将数组元素后移,步长指定每个元素间的间隔100. * param array 待排序数组101. * param startIndex 从哪里开始移102. * param endIndex 到哪个元素止103.
10、 * 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. arrayi + step = arrayi; 108. 109. 110.111. /测试方法112.SuppressWarnings (unchecked) 113. public static final E extends Comparable void test
11、Sort(Sort sorter, E array) 114.115. if (array = null) 116. array = randomArray(); 117. 118. /为了第二次排序,需拷贝一份119. E tmpArr = (E) new Comparablearray.length; 120. System.arraycopy(array, 0, tmpArr, 0, array.length); 121.名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,
12、共 22 页 - - - - - - - - - 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
13、.131. /生成随机数组132.SuppressWarnings (unchecked) 133. private static E extends Comparable E randomArray() 134. Random r = new Random(System.currentTimeMillis();135. Integer a = new Integerr.nextInt(30); 136. for (int i = 0; i a.length; i+) 137. ai = new Integer(r.nextInt(100); 138. 139. return (E) a; 1
14、40. 141. 插入排序直接插入排序一般直接插入排序的时间复杂度为O ( n2 ) ,但是当数列基本有序时,如果按照有数列顺序排时,时间复杂度将改善到O( n ) ,另外,因直接插入排序算法简单,如果待排序列规模不很大时效率也较高。在已经排好序的序列中查找待插入的元素的插入位置,并将待插入元素插入到有序列表中的过程。将数组分成两部分, 初始化时, 前部分数组为只有第一个元素,用来存储已排序元素,我们这里叫 arr1 ;后部分数组的元素为除第一个元素的所有元素,为待名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 -
15、 - - - - - - 第 5 页,共 22 页 - - - - - - - - - 排序或待插入元素,我们这里叫 arr2 。排序时使用二层循环: 第一层对 arr2 进行循环, 每次取后部分数组 (待排序数组)里的第一个元素 (我们称为待排序元素或称待插入元素) e1 ,然后在第二层循环中对 arr1 (已排好序的数组) 从第一个元素往后进行循环,查到第一个大于待插入元素(如果是升序排列)或第一个小于待插入元素 (如果是降序排列)e2 ,然后对 arr1 从 e2 元素开始往后的所有元素向后移,最后把 e1 插入到原来 e2 所在的位置。 这样反复地对 arr2 进行循环,直到 arr2
16、 中所有的待插入的元素都插入到 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 InsertSortE extends Comparable extends Sort 13. 14. /* 15. * 排序算法的实现,对数组中指定的元素进行排序16. * param array 待排序的数组17. * param from
17、 从哪里开始排序18. * param end 排到哪里19. * param c 比较器名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 22 页 - - - - - - - - - 20. */ 21. public void sort(E array, int from, int end, Comparator c) 22. 23. /* 24. * 第一层循环:对待插入(排序)的元素进行循环25. * 从待排序数组断的第二个元素开始循环,到最后一个元素(包括)止26
18、. */ 27. for (int i = from + 1; i = end; i+) 28. /* 29. * 第二层循环:对有序数组进行循环,且从有序数组最第一个元素开始向后循环30. * 找到第一个大于待插入的元素31. * 有序数组初始元素只有一个, 且为源数组的第一个元素,一个元素数组总是有序的32. */ 33. for (int j = 0; j 0) 37. /找到插入点后,从插入点开始向后所有元素后移一位38. move(array, j, i - 1); 39. /将待排序元素插入到有序数组中40. arrayj = insertedElem; 41. break; 42
19、. 43. 44. 45. 46. /=以下是 java.util.Arrays的插入排序算法的实现47. /* 48. * 该算法看起来比较简洁一j 点,有点像冒泡算法。49. * 将数组逻辑上分成前后两个集合,前面的集合是已经排序好序的元素,而后面集合为待排序的50. * 集合,每次内层循从后面集合中拿出一个元素,通过冒泡的形式,从前面集合最后一个元素开51. * 始往前比较,如果发现前面元素大于后面元素,则交换,否则循环退出52. * 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - -
20、 第 7 页,共 22 页 - - - - - - - - - 53. * 总感觉这种算术有点怪怪,既然是插入排序,应该是先找到插入点,而后再将待排序的元素插54. * 入到的插入点上,那么其他元素就必然向后移,感觉算法与排序名称不匹,但返过来与上面实55. * 现比,其实是一样的,只是上面先找插入点,待找到后一次性将大的元素向后移,而该算法却56. * 是走一步看一步,一步一步将待排序元素往前移57. */ 58. /* 59. for (int i = from; i from & pare(arrayj - 1, arrayj) 0; j-) 61. swap(array, j, j -
21、 1); 62. 63. 64. */ 65. 66. 67. /* 68. * 测试69. * param args 70. */ 71. public static void main(String args) 72. Integer intgArr = 5, 9, 1, 4, 1, 2, 6, 3, 8, 0, 7 ; 73. InsertSort insertSort = new InsertSort(); 74. Sort.testSort(insertSort, intgArr); 75. Sort.testSort(insertSort, null); 76. 77. 插入排序算
22、法对于大数组, 这种算法非常慢。但是对于小数组,它比其他算法快。其他算法因为待的数组元素很少,反而使得效率降低。在Java 集合框架中,排序都是借助于 java.util.Arrays来完成的,其中排序算法用到了插入排序、快速排序、归并排序。 插入排序用于元素个数小于7 的子数组排序, 通常比插入排序快的其他排序方法, 由于它们强大的算法是针对大数量数组设计的,所以元素个数少时速度反而慢。希尔排序希尔思想介绍名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 22 页 - -
23、 - - - - - - - 希尔算法的本质是缩小增量排序,是对直接插入排序算法的改进。一般直接插入排序的时间复杂度为O ( n2 ) ,但是当数列基本有序时,如果按照有数列顺序排时,时间复杂度将改善到O( n ) ,另外 , 因直接插入排序算法简单, 如果待排序列规模不很大时效率也较高,Shell 根据这两点分析结果进行了改进,将待排记录序列以一定的增量间隔h 分割成多个子序列,对每个子序列分别进行一趟直接插入排序 , 然后逐步减小分组的步长h ,对于每一个步长h 下的各个子序列进行同样方法的排序, 直到步长为 1 时再进行一次整体排序。因为不管记录序列多么庞大, 关键字多么混乱 , 在先前
24、较大的分组步长h 下每个子序列的规模都不大,用直接插入排序效率都较高。尽管在随后的步长h 递减分组中子序列越来越大, 但由于整个序列的有序性也越来越明显,则排序效率依然较高。这种改进抓住了直接插入排序的两点本质,大大提高了它的时间效率。希尔增量研究综上所述:(1) 希尔排序的核心是以某个增量h 为步长跳跃分组进行插入排序,由于分组的步长 h 逐步缩小,所以也叫“缩小增量排序”插入排序。其关键是如何选取分组的步长序列 ht ,. . . , hk ,. . . , h1 , h0 才能使得希尔方法的时间效率最高;(2) 待排序列记录的个数n 、跳跃分组步长逐步减小直到为1 时所进行的扫描次数 T
25、、增量的和、记录关键字比较的次数以及记录移动的次数或各子序列中的反序数等因素都影响希尔算法的时间复杂度:其中记录关键字比较的次数是重要因素,它主要取决于分组步长序列的选择;(3) 希尔方法是一种不稳定排序算法,因为其排序过程中各趟的步长不同,在第k 遍用 hk 作为步长排序之后,第k +1 遍排序时可能会遇到多个逆序存在,影响排序的稳定性。试验结果表明 ,SHELL 算法的时间复杂度受增量序列的影响明显大于其他因素,选取恰当的增量序列能明显提高排序的时间效率,我们认为第k 趟排序扫描的增量步长为 2k - 1 ,即增量序列为 . . . 2k - 1 ,. . . ,15 ,7 ,3 ,1时较
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年常用排序算法分析与实现 2022 常用 排序 算法 分析 实现
限制150内