理论简介:
将每一个数插入到已经有序的数(左边区域)中的适当位置,当然为了给要插入元素腾出空间,我们需要将其余所有元素在插入之前都向右移动一位。
与选择排序一样,当前索引左边的多有元素都是有序的,但它们的最红位置还不确定,为了给更小的元素腾出空间,它们可能会被移动。但是当索引到达数组的右端时,数组排序就完成了。
分析:
1. 与选择排序不同,选择排序的处理区域是从整个数组一直减小到最后一个数,所以,每次选出的一定是最小的,次小的,第三小的……但是插入排序的处理区域是不断增大的,从最开始的头两个数,一直到整个数组,所以一个小区域里的最小的数不一定是更大区域甚至整个区域理最小的数,所以,左边的有序区域不是就不动了,是可能随着处理区域的扩大而发生变化的。
2. 与选择排序相同,它们都是双重循环,而且外循环的作用都是一个类似于锚的作用,i定下处理区域,只是选择排序处理的是i的右边区域,插入排序处理的是i的左边区域。第二个,它们都是交换排序,选择排序是选择出左边区域最小的,和左边区域第一个数相交换,而插入排序是扫描右边区域,交换不符合升序的数,就像一个齿轮机组。因为插入排序左边的处理区域是从小到大,虽然可能后面会出现更小的,但它也是有序的,所以,齿轮一路传送j到一个位置,这个位置右边的数终于比它大了,这就是内循环结束的时候了,因为左边不可能有比它更大的了。最后一种情况就是一直被齿轮机组传送到了最左边,也结束内循环。
public class Insertion {
public static void sort(int[] a)
{
for(int i=1; i<a.length; i++)
{
for(int j=i; j>0 && a[j]<a[j-1]; j--)
//a[j]<a[j-1]意思是只要j-1比j大,j一直往左走,直到j-1小于j
{
int t = a[j];
a[j] = a[j-1];
a[j-1] = t;
}
}
}
public static void main(String[] args)
{
int[] arr = {3,4,5,8,7,6,9,0,1,2};
Insertion.sort(arr);
for(int i=0; i<10 ; i++)
{
System.out.println(arr[i]);
}
}
}