直接插入排序 (Straight Insertion Sort)
文章部分内容借鉴转载网络、其他博客(如果冒犯请联系我,立马删除)
推荐大家去 skywang12345 ,我觉得十分不错 http://www.cnblogs.com/skywang12345/p/3596881.html
1、striaight insertion sort 基本思想:把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
2、时间复杂度、双重循环
直接插入排序的时间复杂度是O(N2)。
3、空间复杂度
没有拓展新的数组空间 O(1)
看skywang12345 和百度的代码还是有不同的
这是skywang12345,在他的博客中,其实比较好懂,把数列看作有序区和无序区。 skywang12345 的写法比较易懂
但是这个代码虽然易懂,但是必须理解i ,j ,k ,包括 j, k 都有可能变成-1的情况。建议自己debug
/** * 直接插入排序:Java * * @author skywang * @date 2014/03/11 */ public class InsertSort { /* * 直接插入排序 * * 参数说明: * a -- 待排序的数组 * n -- 数组的长度 */ public static void insertSort(int[] a, int n) { int i, j, k; for (i = 1; i < n; i++) { //为a[i]在前面的a[0...i-1]有序区间中找一个合适的位置 for (j = i - 1; j >= 0; j--) if (a[j] < a[i]) break; //如找到了一个合适的位置 if (j != i - 1) { //将比a[i]大的数据向后移 int temp = a[i]; for (k = i - 1; k > j; k--) a[k + 1] = a[k]; //将a[i]放到正确位置上 a[k + 1] = temp; } } } public static void main(String[] args) { int i; int[] a = {20,40,30,10,60,50}; System.out.printf("before sort:"); for (i=0; i<a.length; i++) System.out.printf("%d ", a[i]); System.out.printf("\n"); insertSort(a, a.length); System.out.printf("after sort:"); for (i=0; i<a.length; i++) System.out.printf("%d ", a[i]); System.out.printf("\n"); } }
百度的代码(也是很多官方的)
public class InsertSort{ public void insertSort(int[] array){ for(int i=1;i<array.length;i++)//第0位独自作为有序数列,从第1位开始向后遍历 { if(array[i]<array[i-1])//0~i-1位为有序,若第i位小于i-1位,继续寻位并插入,否则认为0~i位也是有序的,忽略此次循环,相当于continue { int temp=array[i];//保存第i位的值 int k = i - 1; for(int j=k;j>=0 && temp<array[j];j--)//从第i-1位向前遍历并移位,直至找到小于第i位值停止 { array[j+1]=array[j]; k--; } array[k+1]=temp;//插入第i位的值 } } } public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i]); if (i != array.length - 1) { System.out.print(","); } } } }
其中有哨兵
作用
① 进人查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;
② 它的主要作用是:在查找循环中"监视"下标变量j是否越界。一旦越界(即j=0),因为R[0].可以和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件"j>=1")。
其实本质一样啊,虽然skywang12345 说的是那样,但代码里本质
//为a[i]在前面的a[0...i-1]有序区间中找一个合适的位置 for (j = i - 1; j >= 0; j--) if (a[j] < a[i]) break;
就和百度的异曲同工。
其实就是有了基本思想后,再加上 默认前面是有序 这个思想。
百度的集成度比较高。本质上也一样啊。 i j k 三个参数。 两段代码中三个参数连代表的意义也一样
i,表示外遍历的值的index
j是寻找位置,最后是index-1
k是当前交换位置,最后也是index-1??
所以为什么不把j和k做一个变量
是不是有边界问题,我没找到
事实证明没关系..后面我写了不少这样的..
public static void insertSort(int[] array) { for (int i = 1; i < array.length; i++) { if (array[i - 1] > array[i]) { int temp = array[i]; int k = i - 1; for (; k >= 0 && array[k] > temp; k--) { array[k+1]=array[k]; } array[k+1]=temp; } } }