直接插入排序(straight insertion sort)的思想:
直接插入排序的思想在我们的日常生活中也有体现,比如在我们抓牌的时候,我们手里的牌一般都已经排好序了,新抓上来的牌根据大小将它插入到一个合适的位置,直接插入排序的思想也是类似于此。
对于一个待排序的数组,数组分为有序区和无序区,在这里我们假设有序区在数组的左边,无序区在数组的右边,排序的过程就是渐渐将无序区里面的元素加入到有序区里面。有序区的初始状态只有一个元素即数组的第一个元素,无序区的初始状态就是数组剩余的其他元素。无序区待插入的元素 的选择一般都是按照元素的顺序选取,将待插入的元素插入到合适的位置的过程需要比较和交换元素。比较是按从大到小或者从小到大逐个比较,一般都选择从大到小,因为这更方便,在这里我们选择从大到小开始比较。交换可以是如果待插入的元素大于比较的元素就互相交换,也可以是待插入的元素暂时用一个变量存储起来找到合适的位置就将之插入,如果待插入的元素小于比较的元素则将比较的元素后移一个位置。这里给出两种代码的实现方式。
第一种实现方式:
public static void straightInsertionSort(int[] a){
//排序的数组不能为空且至少要有两个元素
if(a == null || a.length < 2){
return;
}
int temp,i,j,k;
boolean flag = false; //用于判断是否插入到正确的位置。第一种方式flag可有可无,有,找到了就不用在判断了。
//i从1开始,[0,i)是有序区,[i,a.length - 1]是无序区
for(i = 1; i < a.length; i++){
//k用来表示待插入的元素的在数组中的下标,j用来表示与待插入的元素比较的元素的下标,在这里也就是前一个元素。
k = i;
j = k - 1;
//当还未插入到正确的位置时就进入循环,当j<0时说明正确的位置是第一个,也要结束循环。
while (!flag && j > -1){
if(a[j] > a[k]) { //当前一个元素大于待插入的元素时,则相互交换。
temp = a[j];
a[j] = a[k];
a[k] = temp;
}else {
flag = true; //已插入到正确的位置
}
k--;
j--;
}
flag = false; //设置下一个待插入的元素为还未插入到正确的位置
}
}
第二种实现方式
public static void straightInsertionSort(int[] a){
//排序的数组不能为空且至少要有两个元素
if(a == null || a.length < 2){
return;
}
int i,j,temp;
boolean flag; //用于判断是否插入到正确的位置。第二种方式flag必须得有,用于。
for(i = 1; i < a.length; i++){
temp = a[i]; //用于暂存待插入的元素
flag = false;
for(j = i -1; j > -1; j--){
if(temp < a[j]){ //如果待插入的元素小于比较的元素则将比较的元素后移一个位置
a[j + 1] = a[j];
}else {
a[j + 1] = temp; //找到正确的位置,将它插入,并结束循环。
flag = true;
break;
}
}
if(!flag){ //如果正确的位置是第一个,flag是false,将它插入
a[0] = temp;
}
}
}