还是一如往常从较为便于理解的递归方式入手:
@Test
@DisplayName("插入排序(递归)")
public void test4() {
int[] arr = {6,1, 3, 2, 5, 4};
sort(arr);
//遍历打印
for (int i : arr) {
System.out.println(i);
}
}
public void sort(int[] arr) {
insrtion(arr, 1);
}
private void insrtion(int[] arr, int i) {
if(i == arr.length){//如果i=arr.length,说明已经排好序了
return;
}
int temp= arr[i];//记录当前要比较的数
int j= i -1;//记录当前要比较的数的前一个数的下标
while(j>=0&&temp< arr[j]){//如果当前要比较的数比前一个数小,就交换
arr[j+1]= arr[j];//把前一个数往后移
j--;//继续往前比较
}
arr[j+1]=temp;//把当前要比较的数放到合适的位置
insrtion(arr, i +1);//继续下一个数的比较
}
逻辑分析:
-
insrtion(int[] arr, int i)
方法:insrtion
方法用于对传入的整数数组arr
进行插入排序。- 参数
i
表示当前要比较的数的下标,初始值为0,即从数组的第一个元素开始比较。 - 在每次递归调用时,我们假设从索引0到索引
i-1
的元素已经排好序,而要将第i
个元素插入到正确的位置。
-
内部逻辑:
- 在每次递归开始时,记录当前要比较的数
temp
为arr[i]
。 - 使用变量
j
初始化为i - 1
,表示当前要比较的数的前一个数的下标。 - 在
while
循环中,比较temp
与arr[j]
的大小,如果temp
比arr[j]
小,则将arr[j]
往后移动一位,继续比较前一个元素,直到找到temp
应该插入的合适位置。在找到合适位置后,temp
的值被插入到arr[j + 1]
中。 - 接着递归调用
insrtion(arr, i + 1)
,继续下一个数的比较,直到i
等于数组的长度arr.length
,即整个数组排序完成。
- 在每次递归开始时,记录当前要比较的数
非递归:
int[] arr = {1, 3, 2, 5, 4};
for(int i=1;i<arr.length;i++){//从第二个数开始比较
int temp=arr[i];//记录当前要比较的数
int j=i-1;//记录当前要比较的数的前一个数的下标
while(j>=0&&temp<arr[j]){//如果当前要比较的数比前一个数小,就交换
arr[j+1]=arr[j];//把前一个数往后移
j--;//继续往前比较
}
arr[j+1]=temp;//把当前要比较的数放到合适的位置
}
//遍历打印
for (int i : arr) {
System.out.println(i);
}
逻辑分析:
-
for
循环for (int i = 1; i < arr.length; i++)
用于遍历整个数组,从第二个元素(索引为1)开始,因为一个元素的数组可以认为是已排序的。 -
在每次循环中,记录当前要比较的数为
temp
,即int temp = arr[i]
。 -
使用变量
j
初始化为i - 1
,表示当前要比较的数的前一个数的下标。 -
在
while
循环中,比较temp
与arr[j]
的大小,如果temp
比arr[j]
小,则将arr[j]
往后移动一位,并将j
向前移动一位,继续比较前一个元素,直到找到temp
应该插入的合适位置。 -
在找到合适位置后,将
temp
的值插入到arr[j + 1]
中,即arr[j + 1] = temp
。 -
循环结束后,整个数组将被排序完成。
-
最后,使用增强型
for
循环遍历打印排序后的数组元素。
插入排序算法是一种简单但效率较低的排序算法,在数据量较大的情况下性能可能较差。对于大规模数据的排序,推荐使用更高效的排序算法,如快速排序或归并排序。但对于小规模数据,插入排序在代码实现上较为简单,可以满足需求。