排序算法第三篇
先放排序算法比较表:
直接插入排序(Insertion Sort):
正如这个排序算法的名字,这是一个简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后往前扫描,找到相应的位置并插入。
算法描述:
步骤一:从第一个元素开始,该元素可以被认为是已排序元素。
步骤二:取出下一个元素,在已排序的元素中从后往前扫描,如果该元素大于新元素则往后移一位,直至找到小于或等于新元素的位置。
步骤三:把新元素放在这个位置的后一位。
步骤四:重复步骤二,三
import java.util.Arrays;
public class InsertionSort {
public static void main(String[] args) {
int[] arr= {14, 10, 9, 7, 12, 2, 1, 4};
insertionSort(arr);
System.out.println(Arrays.toString(arr));
}
public static int [] insertionSort(int[] arr) {
if(arr.length==0||arr==null) {
return arr;
}
int current;
int preIndex;
for(int i=0;i<arr.length-1;i++) {
current=arr[i+1];
preIndex=i;
while(preIndex>=0&&arr[preIndex]>current) {
arr[preIndex+1]=arr[preIndex];
preIndex--;
}
arr[preIndex+1]=current;
}
return arr;
}
}
算法分析:插入排序的时间复杂度分析:在最坏情况下,数组完全逆序,插入第2个元素时要考虑第1个元素,插入第3个元素时要考虑前两个元素,以此类推,插入第n个元素时,要考虑前n-1个元素,这样算下来,结果为n2/2次比较,所以时间复杂度为:O(n2)。
最好情况下,序列是有序的,每次插入元素只需与前一个元素比较,计算下来需比较n-1次。时间复杂度为:O(n)。
平均时间复杂度为:O(n2)
直接插入排序不需要占用额外的内存空间,因此时间复杂度为:O(1)。同时插入排序提供具有稳定性的序列。
希尔排序(Shell Sort):
希尔排序也是一种插入排序,又叫做缩小增量排序(diminishing increment sort),它是简单插入排序经过改进的一个更高效的版本。它与插入排序不同的一点就是,它会比较距离较远的元素。
希尔排序是把记录按一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
算法描述:希尔排序我们首先选择增量为gap=length/2,缩小增量继续以gap=gap/2的方式,这种增量选择我们可以用一个序列来表示:{length/2,length/2/2,…,1},称为增量序列
步骤一:选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
步骤二:按增量序列个数k,对序列进行k 趟排序;
步骤三:每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr= {14, 10, 9, 7, 12, 2, 1, 4};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] sort(int[] arr) {
if(arr.length==0||arr==null) {
return arr;
}
int current;
int preIndex;
int gap =arr.length/2;
while(gap>0) {
for(int i=gap;i<arr.length;i++) {
current=arr[i];
preIndex=i-gap;
while(preIndex>=0&&arr[preIndex]>current) {
arr[preIndex+gap]=arr[preIndex];
preIndex-=gap;
}
arr[preIndex+gap]=current;
}
gap=gap/2;
}
return arr;
}
}
算法解析:最佳情况:T(n) = O(n(logn)^2) 最坏情况:T(n) = O(n(logn)^2) 平均情况:T(n) =O(n(logn)^2)。
没有占用额外的内存空间,因此时间复杂度为O(1)。但是希尔排序是不稳定的,两个相等元素的相对位置在排序后可能会出现变化。