直接插入排序
每次将一个待排序的记录,按其关键字大小插入到前面的已经排好的子表中的适当的位置。直到全部记录插入完成为止。
看图说话,如图所示:
一共有 N 个记录 ,放在 R 列表中 R[0,n-1]
在排序过程中的某一时刻,呈现了如果所示的场景。
其中:
浅绿色为 已经排好序的 部分 称之为 有序区 R[0,i-1]
橘色为 当前元素
橘色+ 蓝色 为尚未排序的 部分 称之为 无序区 R[i,n-1]
我们排序的时候,总是将无序区的第一个记录,放到有序区的合适位置,使有序区长度 +1 ,形成新的有序区 R[0,i]
说人话:
其实最开始的时候,我们就假设该列表的的有序区内仅含有一个记录。即列表的第一个记录 R[0]
其余所有记录都位于无序区,即R[1,n-1] 均为无序区。
开始排序:
从无序区拿第一个元素和有序区的最后一个元素比较,即R[1] 和R[0] 比较,如果 R[1] 小于R[0],那么R[0]向后移动一位,占据R[1]的位置。将原R[1] 插入到R[0] 前面。即原来R[0]的位置。有序区长度+1;如果R[1] 大于R[0],两个记录保持不变。有序区长度依旧+1。有序区编程R[0],R[1]
经过过上一步的比较、排序,现在的无序区的第一个记录就变成了R[2],然后将R[2] 提出来,依次和它前面的记录进行比较,如果发现比R[2]小的记录,那么将R[2]插入到该记录后面。假设一种情况:R[2] 首先和R[1]比较,发现R[2] 大于R[1] 于是将R[1]向后移动一位,注意:先别急着把R[2]插入到R[1]的前面。因为你不知道R[0]和R[2]的关系。所以,继续用R[2]和R[0]比较,假设R[0]小于R[2]了,那么这个时候,再将R[2]放入到R[0]的后面即R[1]的位置。
。。。。
直到所有的记录都这样插入一个遍。
可以这样理解,有一个平台上,上面都是排列好的娃娃(左边一排排)。还有一对杂乱无章的娃娃(右侧圆圈),无乱的堆放在一起。你操作着头顶的机械手,每次从右边的那一大堆的娃娃里面夹起一个,然后向左移动。在平台上,每看到一个娃娃,那么就将机械手里夹着的娃娃和现在你看到的平台上的娃娃那个更大,如果发现平台上的娃娃更大,那么就继续向左移动机械手,看平台上下一个娃娃,如果还是平台上的娃娃大,那么继续向左移动机械手。。。知道你发现机械手的娃娃比平台上的那个娃娃大(假设叫 z ),那么就将机械手上的娃娃放到 z 的后面。其他的比你手里的娃娃大的那些娃娃,在你每一次比较完毕之后,都被人向右移动了一些距离。于是,刚好就给你流出了放置娃娃的空间。
1 /*分为无序[i...n]和有序区[1...i-1],有序区一开始为0,从无序区找到最小值依次放入有序区中*/ 2 public static int[] insertsort(int a[]){ 3 int i,j,index,tmp; 4 /*1.找到index索引,指向i,*/ 5 for ( i = 0; i < a.length; i++) { 6 index=i; 7 /*2.然后在无序区中找到是否还有比index还小的值,如果有将j赋值index*/ 8 for (j=i;j<a.length;j++){ 9 if (a[index]>a[j]) 10 index=j; 11 } 12 /*3.交换index和i的值*/ 13 tmp=a[index]; 14 a[index]=a[i]; 15 a[i]=tmp; 16 } 17 /*4..index重新指向i*/ 18 index=i; 19 20 return a; 21 22 }