基本的排序算法
Selection sort
选择排序是一种简单直观的排序算法。它的工作原理如下:
1:首先在未排序序列中找到最小元素,存放到排序序列的起始位置
2:然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。
3:以此类推,直到所有元素均排序完毕。Source : Selection.java
选择排序的轨迹(每次交换之后数组的内容)
- 算法运行时间和输入无关。这意味着即使输入的数组有序,也要进行一趟扫描。
- 数据的移动最少。交换次数和数组大小是线性关系。
- 选择排序的交换操作介于0和(n-1)次之间。选择排序的比较操作为n(n-1)/2次之间。
insert sort
插入排序都采用in-place在数组上实现。它的工作原理如下:
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 重复步骤2~5 Source : insert.java

插入排序的轨迹(每次插入后数组的内容)
- 插入排序对于部分有序的数组非常有效(可能是最快)。
- 最好情况就是,序列已经是升序排列了,此时需要进行的比较操作需(n-1)次即可。
- 最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。
- 插入排序算法平均时间复杂度为O(n^2)。
- 插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。
shell sort
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
- 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
- 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
希尔排序的思想是使数组中任意间隔为h的元素都是有序的。换句话说,一个h有序数组就是h个互相独立的有序数组组织在一起组成的一个数组。在进行排序的时,如果h很大,就可以将元素移动到很远的地方,为实现更小的h有序创造方便。
1 public static void sort(Comparable[] a) { 2 //{2,4,34,12,78,14,17,98,22,3,44,55}; 3 int N = a.length; 4 // 3x+1 increment sequence: 1, 4, 13, 40, 121, 364, 1093, ... 5 int h = 1; 6 while (h < N / 3) 7 h = 3 * h + 1; 8 while (h >= 1) { 9 // h-sort the array 10 for (int i = h; i < N; i++) { 11 for (int j = i; j >= h && less(a[j], a[j - h]); j -= h) { 12 exch(a, j, j - h); 13 } 14 } 15 h /= 3; 16 } 17 }

一个h有序数组就是h个互相独立的有序数组组织在一起组成的一个数组
实现shell排序的一种方法是对于每个h,用插入排序将h个字数组独立的排序。但是因为自数组是相互独立的,一个更简单的方法是在h-子数组中将每个元素交换到比它大的元素之前去。只需要将插入排序代码中将每个元素的移动距离由1变为h即可。这样希尔排序的实现就实现就黄钻花了一个类似于插入排序但是使用不同的增量的过程。

希尔排序的元素移动轨迹
- 希尔排序更高效是因为它权衡了数组的规模和有序性。各个子数组都很短,排序之后子数组部分有序的,这两种情况适合插入排序。
- 子数组部分有序的程度取决于递增序列的选择。递增序列的缓则没有固定的规则。
- 对于数组内容更多的情况,可以在有限考虑使用希尔排序,该排序不需要使用额外的存储空间,并且代码量很小。
Bubble Sort
冒泡排序對n個項目需要O(n^2)的比較次數,且可以原地排序。儘管這個演算法是最簡單瞭解和實作的排序算法之一,但它對於少數元素之外的數列排序是很沒有效率的。比如在最好的情況,冒泡排序需要O(n^2)次交換,而插入排序只要最多O(n)交換。
冒泡排序演算法的運作如下:
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。
- 針對所有的元素重複以上的步驟,除了最後一個。
- 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
public static void BubbleSorts(int[] num) { int j; boolean flag = true; // set flag to true to begin first pass int temp; // holding variable while (flag) { flag = false; // set flag to false awaiting a possible swap for (j = 0; j < num.length - 1; j++) { if (num[j] > num[j + 1]) // change to > for ascending sort { temp = num[j]; // swap elements num[j] = num[j + 1]; num[j + 1] = temp; flag = true; // shows a swap occurred } } } }
浙公网安备 33010602011771号