一:希尔排序
也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。
希尔排序是非稳定排序算法,先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中,先在各组内进行直接插入排序;
算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
给定实例的shell排序的排序过程
增量序列的取值依次为:
代码如下:
<span style="font-size:14px;">package sort; import java.util.Arrays; public class shellSort { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[] a = {49,38,65,97,76,13,27,49,78,34,12,64,1}; System.out.println("排序之前:"); System.out.println(Arrays.toString(a)); //希尔排序 int len = a.length; while(true) { for(int i=0; i< len; i++) for(int j=i ; j+len < a.length; j +=len) { int temp; if(a[j] > a[j+len]) //大于,则交换 { temp = a[j]; a[j] = a[j+len]; a[j+len] = temp; } } if(len==1) break; len--; } System.out.println("排序之后:"); System.out.println(Arrays.toString(a)); } } </span>
二:桶式排序
该部分转载自:http://blog.csdn.net/apei830/article/details/6596057
桶式排序不再是一种基于比较的排序方法,它是一种比较巧妙的排序方式,但这种排序方式需要待排序的序列满足以下两个特征:
1:待排序列所有的值处于一个可枚举的范围之类;
2:待排序列所在的这个可枚举的范围不应该太大,否则排序开销太大。
排序的具体步骤如下:
(1)对于这个可枚举范围构建一个buckets数组,用于记录“落入”每个桶中元素的个数;
(2)将(1)中得到的buckets数组重新进行计算,按如下公式重新计算:
buckets[i] = buckets[i] +buckets[i-1] (其中1<=i<buckets.length);
桶式排序是一种非常优秀的排序算法,时间效率极高,它只要通过2轮遍历:第1轮遍历待排数据,统计每个待排数据“落入”各桶中的个数,第2轮遍历buckets用于重新计算buckets中元素的值,2轮遍历后就可以得到每个待排数据在有序序列中的位置,然后将各个数据项依次放入指定位置即可。
桶式排序的空间开销较大,它需要两个数组,第1个buckets数组用于记录“落入”各桶中元素的个数,进而保存各元素在有序序列中的位置,第2个数组用于缓存待排数据。
桶式排序是稳定的。如果待排序数据的范围在0~k之间,那么它的时间复杂度是O(k+n)的, 桶式排序算法速度很快,因为它的时间复杂度是O(k+n),而基于交换的排序时间上限是nlg n。
但是它的限制多,比如它只能排整形数组。而且当k较大,而数组长度n较小,即k>>n时,辅助数组C[k+1]的空间消耗较大, 当数组为整形,且k和n接近时, 可以用此方法排序。(有的文章也称这种排序算法为“计数排序”)
代码实现:
- public class BucketSortTest {
- public static int count = 0;
- public static void main(String[] args) {
- int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
- print(data);
- bucketSort(data, 0, 10);
- print(data);
- }
- public static void bucketSort(int[] data, int min, int max) {
- // 缓存数组
- int[] tmp = new int[data.length];
- // buckets用于记录待排序元素的信息
- // buckets数组定义了max-min个桶
- int[] buckets = new int[max - min];
- // 计算每个元素在序列出现的次数
- for (int i = 0; i < data.length; i++) {
- buckets[data[i] - min]++;
- }
- // 计算“落入”各桶内的元素在有序序列中的位置
- for (int i = 1; i < max - min; i++) {
- buckets[i] = buckets[i] + buckets[i - 1];
- }
- // 将data中的元素完全复制到tmp数组中
- System.arraycopy(data, 0, tmp, 0, data.length);
- // 根据buckets数组中的信息将待排序列的各元素放入相应位置
- for (int k = data.length - 1; k >= 0; k--) {
- data[--buckets[tmp[k] - min]] = tmp[k];
- }
- }
- public static void print(int[] data) {
- for (int i = 0; i < data.length; i++) {
- System.out.print(data[i] + "\t");
- }
- System.out.println();
- }
- }
运行结果:
- 5 3 6 2 1 9 4 8 7
- 1 2 3 4 5 6 7 8 9
至此排序算法我已经总结的不少了,所谓是各有千秋吧,当然还有许多排序的算法我没有进行总结和实现(说不到哪天脑子发热了就会续着总结完吧),比如说:
外部排序(针对大文件)
间接排序(针对复杂的数据结构)
冒泡排序(最经典的也是最简单的)
计数排序
基数排序
排序算法之快速排序
排序算法之堆排序
排序算法之归并排序,插入排序
排序算法之希尔排序,桶式排序