直接插入排序是插入排序算法中最简单的排序方法。
基本思想:依次将待排序序列中的每一个记录插入到一个已经排好序的序列中。
简单可以理解为:将待排序序列分为有序区和无序区,将无序区中每一个记录分别与有序区中记录比较,找到合适位置插入到有序区中,如此进行,直至无序区没有记录,则待排序序列全部有序。
算法开始时,由于不知道待排序区的有序区和无序区。因此可以将待排序序列第一个记录看作 有序区的第一个记录,待排序区除第一个记录外全部当作无序区看待。
此文排序按从小到大排序,反之亦然。
算法过程: 从无序区选第一个记录(即原来待排序区的第二个记录)与有序区第一个记录相比较,如果比有序区记录小,则互换位置,无序区第一个记录进入有序区。如果比有序区记录大,无序区第一个记录同样进入有序区,后面元素开始比较。
需要注意的是后面元素比较时,需要从有序区最后一个元素开始向前比较,因为插入排序时,需要考虑到插入前记录的后移(即给待插入记录留出插入的位置,需要将比该记录大的记录向后移一个单位)如果从有序区第一个元素开始比,找到插入位置后,该位置后面的记录仍没有办法后移给给该记录留出空位,因此不能从有序区第一个元素开始比。
另外为了方便与有序区元素的比较,并且不会因为互换位置而影响序列的值,需要添加哨兵,将待插入的值赋予哨兵,让哨兵去与有序区记录比较。
例如: 初始待排序序列为:12 15 9 20 6 31 24
初始有序区: 12 无序区: 15 9 20 6 31 24
第一次算法进行: 15>12 则 有序区: 12 15 无序区: 9 20 6 31 24
第二次:9<15 9<12 则 有序区: 9 12 15 无序区:20 6 31 24
第三次:20>15 有序区:9 12 15 20 无序区:6 31 24
第四次:6<20 6<15 6<12 6<9 有序区:6 9 12 15 20 无序区: 31 24
第五次:31>20 有序区: 6 9 12 15 20 31 无序区: 24
第六次: 24<31 24>20 有序区:6 9 12 15 20 24 31 完成。
具体代码实现:
1. 知道待排序序列元素个数,而且需要全部排序
public static void charu(int[] a,int n) {
int j;
int t=0; //哨兵
for(int i=1;i<n; i++) { //从无序区第一个元素开始,有序区元素为a[0]
t=a[i]; //待排序记录赋值给哨兵
for(j=i-1;j>=0;j--) { //i-1为有序区最后一个元素
if(t<a[j])
a[j+1]=a[j]; //记录后移
else
break;
}
a[j+1]=t; //将待插入记录插入有序区中
}
for(int i=0;i<n; ++i) {
System.out.print(a[i]+ " ");
}
System.out.println();
}
2.如果需要从控制台输入待排序序列,或者只排序n个记录
public static void charu(int[] a,int n) {
int j;
int t=0;
for(int i=1;i<n; i++) {
t=a[i];
for(j=i-1;j>=0;j--) {
if(t<a[j])
a[j+1]=a[j];
else
break;
}
a[j+1]=t;
}
for(int i=0;i<n; ++i) {
System.out.print(a[i]+ " ");
}
System.out.println();
}
区别在于构建函数的方式不同。