排序
直接插入排序:
主要思想:将待排序列(无序区)中的每一个记录,依次插入到一个已经排好的序列中(有序区)。括号中为已经排好的序列。
例如: 括号中为已经排好的序列(有序区)* 初始序列 [12] 15, 9, 20, 6, 31, 24 (第一个数为已排序列)
* 第一趟结果 [12, 15] 9, 20, 6, 31, 24(将待排序列的第一个数:15插入到正确位置)
* 第二趟结果 [9, 12, 15] 20, 6, 31, 24 (将待排序列的第一个数:9插入到正确位置)*第三趟结果 [9, 12, 15,20] 6, 31, 24 (将待排序列的第一个数:20插入到正确位置)这样依次类推直到待排序列中没有记录,而前面的有序区就是整个排好的序列。
/**
* 插入排序: 直接插入排序
*/
@Override
public void insertSort(T[] t) {
int j; //表示无序区的第一个记录
for (int i = 1; i < t.length; i++) {
T tmp = t[i];
for (j = i; j > 0 && compare(tmp, t[j - 1]); j--) { //tmp 小于 t[j-1] 返回真
t[j] = t[j - 1]; // 有序区比无序区第一个大的后移,知道找到插入位置
}
t[j] = tmp;
}
System.out.println("直接插入排序:");
print(t);// 打印数组
}
这里的compare 、 print 方法将在讲解完全部排序介绍,这里仍然才用泛型。
性能分析:(1)在最好情况下,待排序列是正序,每趟只需与有序序列的最后一个记录比较一次。总的比较次数为n-1次,时间复杂度为O(n)。(2) 在最坏情况下,待排序列为逆序,第i趟插入,每次取出无序区的元素都要与与前面i-1个记录比较并且移动,时间复杂度为O(n*N)。(3)等概率情况下每个记录要比较有序区中的一半。第一趟最多比较1次,第二趟最多比较2次,最后一趟最多比较N-1次。
稳定性: 若两个记录A和B值相等,但是排序后A、B的先后次序保持不变,则这种排序是稳定的,否则就是不稳定。所以总比较次数:1+2+3+4+......+N-1 = (N*(N-1))/2 = O(N*N)。平均比较次数在总的比较次数上除以2,时间复杂度不变。
总结: 直接插入排序简单、容易实现,当记录叫少是可以选择,但是记录较多时大量的比较移动,效率非常低。直接插入排序是一种稳定的排序方法。