讲优化之前先给大家开个传送门方便阅读之前的代码:
Java排序算法——插入排序(Insertion Sort)https://blog.csdn.net/babbfqb93/article/details/123043711
之前和大家一起总结的直接排序中提到的那个方法是为了帮助大家更好的理解“插入”与“比较”的区别,不过实际上将a[3]插入到a[1]的位置用之前的做法是
将a[3]之前,a[1]之后的所有元素均向后移动一个,即a[1],a[2]均向后移动一位,然后将a[3]的值赋值给a[1]
这种方式和
a[3]与a[2]交换,a[2](原a[3])与a[1]交换
这两种方式明显是一样的,无论是原本意上的理解,和代码翻译这逻辑都是后者有更大的又是,于是乎,我们可以把插入的swap(int[] iArray,int i,int j)方法做一个小小的修改:
原代码:
//将下标为i的元素插入到下标为j的元素
public static void swap(int[] iArray,int i,int j){
//先将j下标位置存储
int temp = iArray[i];
//当i>j的时候需要循环,直到j与i坐标相当,每次将j之前一个数向后移动一位,j--
for(;i>j;i--){
iArray[i]=iArray[i-1];
}
//最后将i下标设置成被插入数的值
iArray[j]=temp;
}
修改为:
//将下标为i的元素插入到下标为j的元素
public static void swap(int[] iArray,int i,int j){
int tmp = iArray[i];
iArray[i] = iArray[j];
iArray[j] = tmp;
}
这种常规的交换,然后,我们可以把插入排序代码进行精简
原代码为:
public static void insertionSort(int[] iArrays){
//循环整体数据
for(int i =0;i<iArrays.length-1;i++) {
//默认和0进行交换
int index = 0;
//被比较的数(“红色”)
int temp = iArrays[i+1];
//遍历之前的“有序数组”,从总循环次数+1开始遍历
for (int j = i+1; j > 0; j--) {
//如果需比较的数字大于之前的某一个元素,记录元素的下标用于插入
if ( temp > iArrays[j - 1]) {
index = j;
//因为之前为有序的所以记录坐标就可以break了
break;
}
}
//插入交换
swap(iArrays, i+1, index);
}
}
由于插入的方法不同了,所以我们可以先将原代码注释掉,改成如果“红色”的数比原本的数字小,则交换两个数(原本如果找到了重点就break,也修改为一直交换下去就可以了)
public static void insertionSort(int[] iArrays){
//循环整体数据
for(int i =0;i<iArrays.length-1;i++) {
//默认和0进行交换
int index = 0;
//被比较的数(“红色”)
int temp = iArrays[i+1];
//遍历之前的“有序数组”,从总循环次数+1开始遍历
for (int j = i+1; j > 0; j--) {
//如果需比较的数字大于之前的某一个元素,记录元素的下标用于插入
/**
*if ( temp > iArrays[j - 1]) {
* index = j;
* //因为之前为有序的所以记录坐标就可以break了
* break;
*}
*/
if(iArrays[j]<iArrays[j - 1]){
swap(iArrays,j,j-1);
}
}
插入交换
//swap(iArrays, i+1, index);
}
}
此时我们发现中间变量index和temp都没用到了,可以直接删除,进一步精简
public static void insertionSort(int[] iArrays){
//循环整体数据
for(int i =0;i<iArrays.length-1;i++) {
//默认和0进行交换
//int index = 0;
//被比较的数(“红色”)
//int temp = iArrays[i+1];
//遍历之前的“有序数组”,从总循环次数+1开始遍历
for (int j = i+1; j > 0; j--) {
//如果需比较的数字大于之前的某一个元素,记录元素的下标用于插入
/**
*if ( temp > iArrays[j - 1]) {
* index = j;
* //因为之前为有序的所以记录坐标就可以break了
* break;
*}
*/
if(iArrays[j]<iArrays[j - 1]){
swap(iArrays,j,j-1);
}
}
插入交换
//swap(iArrays, i+1, index);
}
}
我们把所有被注释掉的代码都删掉方便阅读
public static void insertionSort(int[] iArrays){
//循环整体数据
for(int i =0;i<iArrays.length-1;i++) {
for (int j = i+1; j > 0; j--) {
if(iArrays[j]<iArrays[j - 1]){
swap(iArrays,j,j-1);
}
}
}
}
此时我们发现for里面只有满足if条件的时候才执行代码,所以我们可以把这个if条件添加到for循环的进入逻辑判断中,即:
public static void insertionSort(int[] iArrays){
//循环整体数据
for(int i =0;i<iArrays.length-1;i++) {
for (int j = i+1; j > 0 && iArrays[j]<iArrays[j - 1]; j--) {
swap(iArrays,j,j-1);
}
}
}
这样一看是不是只需要三行代码就实现了直接插入排序?很简单吧?那么我们先试一下这个排序的效果:
好,我说完了。