插入排序思路

import com.alibaba.fastjson.JSON;

import java.util.Arrays;
import java.util.List;

//插入排序
class Scratch {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 4, 2, 7, 0, 3);
        insertion(list);
        System.out.println(JSON.toJSONString(list));//[0,1,2,3,4,7]
    }

    public static List<Integer> insertion(List<Integer> list) {
        for (int i = 1; i <= list.size() - 1; i++) {
            for (int j = i; j > 0; j--) {
                if (greater(list.get(j - 1), list.get(j))) {
                    exch(list, j - 1, j);
                } else {
                    break;
                }
            }
        }
        return list;
    }

    /**
     * 比较a是否大于b的值
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean greater(Integer a, Integer b) {
        return a > b;
    }

    /**
     * 替换list中下标为i和下标为j的值
     *
     * @param list
     * @param i
     * @param j
     */
    public static void exch(List<Integer> list, Integer i, Integer j) {
        Integer temp = list.get(i);
        list.set(i, list.get(j));
        list.set(j, temp);
    }
}

思路:外层从下标1开始遍历,用外层下标的值和该下标之前下标的值进行比较(倒序)。例如第六趟排序[1,2,3,4,10,12,5,6]。此时是外层遍历到下标为6的值(对应数值为5),将5与前面的数值倒序循环比较。首先5先和12比,5比12小,所以5、12交换位置(此时5对应的下标是5,12对应的下标是6);然后5和10比,5比10小,所以5、10交换位置;然后5和4比,5比4大,那么也就代表了5会比4这个值对应的下标之前的所有值都大,也就没有必要继续循环对比了,此时就可以跳出内层循环,然后外层循环从下标为7继续比较,以此类推。

图解: 

### 插入排序的详细思路 插入排序的核心思想是通过构建有序序列的方式,逐步将未排序的数据插入到已排序的部分中。具体来说: - **初始状态**:假设数组的第一个元素已经是一个有序子序列。 - **迭代过程**:从第二个元素开始,依次将其插入到当前已排序部分中的合适位置。 - **插入操作**:为了给新元素腾出空间,需要将大于该元素的所有已排序项向右移动一位。 时间复杂度为 \( O(N^2) \)[^1],而空间复杂度仅为 \( O(1) \),因为它是原地排序算[^2]。 --- ### 图解过程 以下是插入排序的一个典型例子及其图解说明: #### 输入数组 \[ A = [5, 2, 9, 1, 5, 6] \] #### 排序步骤 1. 初始状态: 已排序部分为 `[5]`,其余部分为 `[2, 9, 1, 5, 6]`。 2. 将 `2` 插入到已排序部分: - 比较 `2` 和 `5`,发现 `2 < 5`,所以将 `5` 向后移动一位。 - 结果变为 `[2, 5, 9, 1, 5, 6]`。 3. 将 `9` 插入到已排序部分: - 比较 `9` 和 `5`,发现 `9 >= 5`,无需移动任何元素。 - 结果仍为 `[2, 5, 9, 1, 5, 6]`。 4. 将 `1` 插入到已排序部分: - 比较 `1` 和 `9` → 移动 `9`; - 比较 `1` 和 `5` → 移动 `5`; - 比较 `1` 和 `2` → 移动 `2`; - 最终结果为 `[1, 2, 5, 9, 5, 6]`。 5. 将 `5` 插入到已排序部分: - 比较 `5` 和 `9` → 不需移动; - 比较 `5` 和 `5` → 发现相同,不改变顺序(稳定性体现)。 - 结果为 `[1, 2, 5, 5, 9, 6]`。 6. 将 `6` 插入到已排序部分: - 比较 `6` 和 `9` → 移动 `9`; - 比较 `6` 和 `5` → 停止比较并将 `6` 放置在此处。 - 最终结果为 `[1, 2, 5, 5, 6, 9]`。 最终完成整个排序过程。 --- ### Python 实现代码 下面是基于上述逻辑编写的插入排序代码示例: ```python def insertion_sort(arr): n = len(arr) for i in range(1, n): # 遍历待排序部分 key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: # 找到插入的位置 arr[j + 1] = arr[j] # 右移较大的元素 j -= 1 arr[j + 1] = key # 插入目标值 return arr # 测试用例 example_array = [5, 2, 9, 1, 5, 6] sorted_array = insertion_sort(example_array[:]) print(sorted_array) ``` --- ### 性能特点 - **最佳情况**:如果输入数据本身已经是升序排列,则只需要执行一次遍历即可完成排序,时间复杂度降为 \( O(N) \)[^2]。 - **最差情况**:当输入数据完全逆序时,每次都需要进行最大次数的比较和交换,总的操作数达到 \( N*(N-1)/2 \),即 \( O(N^2) \)[^4]。 - **平均情况**:对于随机分布的数据集,期望的时间复杂度同样为 \( O(N^2) \)[^1]。 此外,由于只涉及相邻元素之间的调整,因此不需要额外存储空间支持,这使得它的空间复杂度始终保持在常量级别 \( O(1) \)[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值