插入排序算法详解(从前往后)
A. 把第一个元素当成一个升序数组-----升序
1.核心代码
for (int i = 0; i <numbers.length-1; i++) {
//每次把第一个元素当成升序数组,然后紧邻着的后面的元素进行大小比较(次数为i+1)
//使组合形成的新数组是升序数组
for (int j = i+1; j>0; j--) {
//如果前一个数比后一个数大,就进行交换(小者在前)
//否则就无需就行后续的比较操作,直接开始下一次组合(break的作用)
if(numbers[j-1]>numbers[j]){
int temp=numbers[j-1];
numbers[j-1]=numbers[j];
numbers[j]=temp;
}else{
break;
}
}
}
2.常见问题点分析
2.1 如何进行插入排序???
解决方案: 1.把第一个元素当成升序数组
2.拿紧邻的元素p与升序数组组合一起当成成一个新数组
3.拿p与原数组里面的每一个数(从后往前的顺序)进行比较大小,
若比它小,就进行交换(小者在前,为升序)
否则无需执行后面的循环操作了,
此时可以把结果当成一个新的升序数组
否则的理由:因为p大于等于原升序数组里面的最后一个数字了,
那么此时后面的继续比较就没有任何意义了(再这么比较也不会有任何变化的)
循环往复执行上述步骤2,3,直至满足循环次数=数组长度-1,循环才结束
2.2 插入排序的循环次数为多少?
解决方案:循环次数=数组长度-1
2.3 插入排序具体操作(数字是这么移动的)过程
以数组int[] a=[4,-2,-6,3,1]为列
排序次数 | 需要排序的数组部分 | 排序前的数组 | 排序后的数组 |
---|---|---|---|
第1次 | [4,-2] | [4,-2,-6,3,1] | [-2,4,-6,3,1] |
第2次 | [-2,4,-6] | [-2,4,-6,3,1] | [-6,-2,4,3,1] |
第3次 | [-6,-2,4,3] | [-6,-2,4,3,1] | [-6,-2,3,4,1] |
第4次 | [-6,-2,3,4,1] | [-6,-2,3,4,1] | [-6,-2,1,3,4] |
2.4 为什么核心代码处12行要使用break跳出当前循环???
解决方案:因为默认有序为升序,且紧邻元素p比原数组的最后一个数据都大,
那么就没有任何交换的必要了。
2.5 内层循环为啥是i+1开始?
解答: a.每次都是从紧邻元素与原数组的最后一个位置进行比较大小开始的
b.且每次新的紧邻元素会每次往后移动一个,这与i的变化规律一致
2.6 紧邻元素与升序数组组合一起的新数组需要进行比较大小几次,才能得到新的升序数组??
解答: 当紧邻元素位置为0+1=1时,需要比较1次
当紧邻元素位置为1+1=1时,需要比较2次
…
当紧邻元素位置为n+1时,需要比较n+1次
因而需要比较i+1次(内层循环j不可以取值到位置0)
3.运行截图
4.源代码
public class InsertSort01 {
public static void main(String[] args) {
System.out.println("插入排序之升序(假定第一个元素构成的数组为升序数组)");
int[] numbers={4,-2,-6,3,1};
System.out.println("排序前:");
for (int temp01:numbers
) {
System.out.print(temp01+"\t");
}
for (int i = 0; i <numbers.length-1; i++) {
//每次把第一个元素当成升序数组,然后紧邻着的后面的元素进行大小比较(次数为i+1)
//使组合形成的新数组是升序数组
for (int j = i+1; j>0; j--) {
//如果前一个数比后一个数大,就进行交换(小者在前)
//否则就无需就行后续的比较操作,直接开始下一次组合
if(numbers[j-1]>numbers[j]){
int temp=numbers[j-1];
numbers[j-1]=numbers[j];
numbers[j]=temp;
}else{
break;
}
}
System.out.println("\n第"+(i+1)+"次排序后:");
for (int temp02:numbers
) {
System.out.print(temp02+"\t");
}
}
System.out.println("\n插入排序后的结果为:");
for (int temp03:numbers
) {
System.out.print(temp03+"\t");
}
}
}
B. 把第一个元素当成一个降序数组-----降序
1.核心代码
for (int i = 0; i <numbers.length-1; i++) {
//每次把第一个当成降序数组,然后紧邻着的后面的元素进行大小比较(次数为i+1)
//使组合形成的新数组是降序的
for (int j = i+1; j>0; j--) {
//如果前一个数比后一个数小,就进行交换(大者在前)
//否则就无需就行后续的比较操作,直接开始下一次组合
if(numbers[j-1]<numbers[j]){
int temp=numbers[j-1];
numbers[j-1]=numbers[j];
numbers[j]=temp;
}else{
break;
}
}
}
2.常见问题点分析
2.1 如何进行插入排序???
解决方案: 1.把第一个元素当成升序数组
2.拿紧邻的元素p与升序数组组合一起当成成一个新数组
3.拿p与原数组里面的每一个数(从后往前的顺序)进行比较大小,
若比它大,就进行交换(大者在前,为降序)
否则无需执行后面的循环操作了,
此时可以把结果当成一个新的升序数组
否则的理由:因为p小于等于原升序数组里面的最后一个数字了,
那么此时后面的继续比较就没有任何意义了(再这么比较也不会有任何变化的)
循环往复执行上述步骤2,3,直至满足循环次数=数组长度-1,循环才结束
2.2 插入排序的循环次数为多少?
解决方案:循环次数=数组长度-1
2.3 插入排序具体操作(数字是这么移动的)过程
以数组int[] a=[-88,-2,-6,3,1]为列
排序次数 | 需要排序的数组部分 | 排序前的数组 | 排序后的数组 |
---|---|---|---|
第1次 | [-88,-2] | [-88,-2,-6,3,1] | [-2,-88,-6,3,1] |
第2次 | [-2,-88,-6] | [-2,-88,-6,3,1] | [-2,-6,-88,3,1] |
第3次 | [-2,-6,-88,3] | [-2,-6,-88,3,1] | [3,-2,-6,-88,1] |
第4次 | [3,-2,-6,-88,1] | [3,-2,-6,-88,1] | [3,1,-2,-6,-88] |
2.4 为什么核心代码处12行要使用break跳出当前循环???
解决方案:因为默认有序为降序,且紧邻元素p比原数组的最后一个数据都小,
那么就没有任何交换的必要了。
2.5 内层循环为啥是i+1开始?
解答: a.每次都是从紧邻元素与原数组的最后一个位置进行比较大小开始的
b.且每次新的紧邻元素会每次往后移动一个,这与i的变化规律一致
2.6 紧邻元素与升序数组组合一起的新数组需要进行比较大小几次,才能得到新的降序数组??
解答: 当紧邻元素位置为0+1=1时,需要比较1次
当紧邻元素位置为1+1=1时,需要比较2次
…
当紧邻元素位置为i+1时,需要比较i+1次
因而需要比较i+1次(内层循环j不可以取值到位置0)
3.运行截图
4.源代码
public class InsertSort02 {
public static void main(String[] args) {
System.out.println("插入排序之从前往后排序(假定第一个元素构成的数组为降序数组)");
int[] numbers={-88,-2,-6,3,1};
System.out.println("排序前:");
for (int temp01:numbers
) {
System.out.print(temp01+"\t");
}
for (int i = 0; i <numbers.length-1; i++) {
//每次把第一个当成降序数组,然后紧邻着的后面的元素进行大小比较(次数为i+1)
//使组合形成的新数组是降序的
for (int j = i+1; j>0; j--) {
//如果前一个数比后一个数小,就进行交换(大者在前)
//否则就无需就行后续的比较操作,直接开始下一次组合
if(numbers[j-1]<numbers[j]){
int temp=numbers[j-1];
numbers[j-1]=numbers[j];
numbers[j]=temp;
}else{
break;
}
}
System.out.println("\n第"+(i+1)+"次排序后:");
for (int temp02:numbers
) {
System.out.print(temp02+"\t");
}
}
System.out.println("\n插入排序后的结果为:");
for (int temp03:numbers
) {
System.out.print(temp03+"\t");
}
}
}