排序算法总结
排序算法 | 冒泡 | 选择 | 插入 | 希尔 | 快速 | 归并 | 堆 | 基数 |
---|---|---|---|---|---|---|---|---|
平均时间复杂度 | O(n2) | O(n2) | O(n2) | O(n1.5) | O(N*logN) | O(N*logN) | O(N*logN) | O(d(n+r)) |
冒泡排序(BubbleSort)
基本思想:两个数比较大小,较大的数下沉,较小的数冒起来。
过程:
- 比较相邻的两个数据,如果第二个数小,就交换位置。
- 从后向前两两比较,一直到比较最前两个数据,最终最小数被交换到起始位置,这样第一个最小数的位置就排好了。
- 继续重复上述过程,依次将2、3、…n-1个最小数排好位置。
java代码实现:
1 | public class SortClass { |
选择排序(SelectionSort)
基本思想:
- 在长度为 N 的数组中,第一次遍历 n-1 个数,找到最小的数值与第一个元素交换,
- 第二次遍历 n-2 个数,找到最小的数值与第二个元素交换,
- 依次类推,
- 第 n-1 次遍历,找到最小的数值与第 n-1 个元素交换,排序完成。
java代码实现:
1 | public class SortClass { |
插入排序(InsertionSort)
基本思想:
- 在要排序的一组数中,假设前 n-1 个数已经排好序,
- 现将第 n 个数插到前面的有序数列中,使得这 n 个数也是排好顺序的,
- 如此反复循环,直到排好顺序。
java代码实现:
1 | public class SortClass { |
快速排序(QuickSort)
基本思想:(分治)
- 先从数列中取出一个数作为 key 值,
- 将比这个数小的全部放在它的左边,大于或等于它的数全部放在右边,
- 对左右两个小数列重复第二步,直至各区间只有一个数。
辅助理解:挖坑填数
- 初始时:i=0,j=9,key=72,arr={72 , 6 , 57 , 88 , 60 , 42 , 83 , 73 , 48 , 85}
由于已将 arr[0] 的值保存到 key 中,可以理解成在数组 arr[0] 上挖了个坑,可以将其它数据填充进来,
(– , 6 , 57 , 88 , 60 , 42 , 83 , 73 , 48 , 85)
从 j 开始向前找一个比 key 小的数,如当 j=8 时符合条件,则 arr[0] =arr[8] 并 i++,
(48 , 6 , 57 , 88 , 60 , 42 , 83 , 73 , 48 , 85)
这样坑 arr[0] 解决了,但又多出了一个新坑 arr[8],
(48 , 6 , 57 , 88 , 60 , 42 , 83 , 73 , – , 85)
这次从 i 开始向后找一个大于 key 的数,如当 i=3 时符合条件,则 arr[8] = arr[3] 并 j- -,
(48 , 6 , 57 , 88 , 60 , 42 , 83 , 73 , 88 , 85) - 此时,i=3,j=7,key=72,arr={48 , 6 , 57 , 88 , 60 , 42 , 83 , 73 , 88 , 85}
再重复上述步骤,先从后面找,再从前面找,
从 j 开始向前找,当 j=5 时符合条件,则 arr[3] = arr[5] 并 i++,
(48 , 6 , 57 , 42 , 60 , 42 , 83 , 73 , 88 , 85)
从 i 开始向后找,当 i=5 时,由于 i==j 退出,
此时,i=j=5,而 arr[5] 刚好又是上次挖的坑,因此将 key 填入 arr[5],
(48 , 6 , 57 , 42 , 60 , 72 , 83 , 73 , 88 , 85) - 此时,i=3,j=5,key=72,arr={48 , 6 , 57 , 42 , 60 , 72 , 83 , 73 , 88 , 85}
可以看出 arr[5] 前面的数字都小于它,而后面的数字都大于它,
因此再对 arr[0…4] 和 arr[6…9] 这两个子区间重复上述步骤即可。
java代码实现:
1 | public class SortClass { |
归并排序(MergeSort)
基本思想:
- 建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。
- 如何将两个有序数列合并,可以比较两个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数,然后再比较,如有数列为空,则直接将另一个数列的数据依次取出即可。
java代码实现:
1 | public class SortClass { |
解决了上述的合并有序数列问题,再看归并排序,其基本思路就是将数组分成2组,各自再分成2组,依此类推,当分出的小组只有一个数据时,可认为这个小组组内已经达到了有序,然后再合并相邻的2个小组就可以了,这样通过先递归的分解数列,再合并数列就完成了归并排序。
平均时间复杂度:O(N*logN))
归并排序的效率是比较高的,设数列长为 N,将数列分开成小数列一共要 logN 步,每步都是一个合并有序数列的过程,时间复杂度可以记为 O(N),故一共为 O(N*logN)。
java代码实现:
1 | public class SortClass { |