DeepSeek Java 插入排序实现

Java 插入排序实现

以下是插入排序在 Java 中的完整实现,包含多种写法和详细注释。

基础版本

java 复制代码
public class InsertionSort {
    
    /**
     * 插入排序基础实现 (升序)
     * @param arr 待排序的数组
     */
    public static void insertionSort(int[] arr) {
        // 从第二个元素开始遍历(第一个元素默认已排序)
        for (int i = 1; i < arr.length; i++) {
            int key = arr[i];  // 当前待插入的元素
            int j = i - 1;     // 从当前元素的前一个位置开始比较
            
            // 将比key大的元素都向后移动一位
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            
            // 将key插入到正确位置
            arr[j + 1] = key;
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {5, 2, 4, 6, 1, 3};
        
        System.out.println("排序前: " + Arrays.toString(arr));
        insertionSort(arr);
        System.out.println("排序后: " + Arrays.toString(arr));
    }
}

完整实现(带详细注释和测试)

java 复制代码
import java.util.Arrays;

public class InsertionSort {
    
    /**
     * 插入排序 - 基础版本
     * 时间复杂度: 最好O(n), 最坏O(n²), 平均O(n²)
     * 空间复杂度: O(1)
     * 稳定性: 稳定
     */
    public static void insertionSort(int[] arr) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        
        // 从第二个元素开始(索引1),因为第一个元素默认已排序
        for (int i = 1; i < arr.length; i++) {
            int key = arr[i];  // 当前要插入的元素
            int j = i - 1;     // 从i的前一个位置开始比较
            
            // 在已排序部分从后往前查找插入位置
            // 同时将比key大的元素向后移动
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];  // 元素后移
                j--;
            }
            
            // 将key插入到正确位置
            arr[j + 1] = key;
            
            // 打印每轮排序结果(可选,用于理解算法过程)
            // System.out.println("第" + i + "轮: " + Arrays.toString(arr));
        }
    }
    
    /**
     * 插入排序 - 泛型版本,支持任何实现了Comparable接口的类型
     */
    public static <T extends Comparable<T>> void insertionSortGeneric(T[] arr) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        
        for (int i = 1; i < arr.length; i++) {
            T key = arr[i];
            int j = i - 1;
            
            while (j >= 0 && arr[j].compareTo(key) > 0) {
                arr[j + 1] = arr[j];
                j--;
            }
            
            arr[j + 1] = key;
        }
    }
    
    /**
     * 插入排序 - 带比较器的版本
     */
    public static <T> void insertionSortWithComparator(T[] arr, java.util.Comparator<T> comparator) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        
        for (int i = 1; i < arr.length; i++) {
            T key = arr[i];
            int j = i - 1;
            
            while (j >= 0 && comparator.compare(arr[j], key) > 0) {
                arr[j + 1] = arr[j];
                j--;
            }
            
            arr[j + 1] = key;
        }
    }
    
    /**
     * 插入排序 - 降序排列
     */
    public static void insertionSortDesc(int[] arr) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        
        for (int i = 1; i < arr.length; i++) {
            int key = arr[i];
            int j = i - 1;
            
            // 修改比较条件为 <,实现降序
            while (j >= 0 && arr[j] < key) {
                arr[j + 1] = arr[j];
                j--;
            }
            
            arr[j + 1] = key;
        }
    }
    
    /**
     * 二分查找插入排序 - 优化版本
     * 使用二分查找来找到插入位置,减少比较次数
     */
    public static void binaryInsertionSort(int[] arr) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        
        for (int i = 1; i < arr.length; i++) {
            int key = arr[i];
            
            // 使用二分查找找到插入位置
            int left = 0;
            int right = i - 1;
            int pos = i;  // 默认插入位置
            
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (arr[mid] > key) {
                    pos = mid;
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            
            // 将元素向后移动
            for (int j = i - 1; j >= pos; j--) {
                arr[j + 1] = arr[j];
            }
            
            // 插入元素
            arr[pos] = key;
        }
    }
    
    // 测试方法
    public static void main(String[] args) {
        System.out.println("=== 插入排序测试 ===");
        
        // 测试1: 基础版本
        int[] arr1 = {5, 2, 4, 6, 1, 3};
        System.out.println("原始数组: " + Arrays.toString(arr1));
        insertionSort(arr1);
        System.out.println("升序排序: " + Arrays.toString(arr1));
        
        // 测试2: 降序版本
        int[] arr2 = {5, 2, 4, 6, 1, 3};
        insertionSortDesc(arr2);
        System.out.println("降序排序: " + Arrays.toString(arr2));
        
        // 测试3: 泛型版本
        Integer[] arr3 = {5, 2, 4, 6, 1, 3};
        System.out.println("泛型排序前: " + Arrays.toString(arr3));
        insertionSortGeneric(arr3);
        System.out.println("泛型排序后: " + Arrays.toString(arr3));
        
        // 测试4: 字符串排序
        String[] arr4 = {"banana", "apple", "cherry", "date"};
        System.out.println("字符串排序前: " + Arrays.toString(arr4));
        insertionSortGeneric(arr4);
        System.out.println("字符串排序后: " + Arrays.toString(arr4));
        
        // 测试5: 二分插入排序
        int[] arr5 = {5, 2, 4, 6, 1, 3};
        System.out.println("二分插入前: " + Arrays.toString(arr5));
        binaryInsertionSort(arr5);
        System.out.println("二分插入后: " + Arrays.toString(arr5));
        
        // 测试6: 性能比较
        System.out.println("\n=== 性能测试 ===");
        int[] largeArr = new int[10000];
        for (int i = 0; i < largeArr.length; i++) {
            largeArr[i] = (int) (Math.random() * 10000);
        }
        
        int[] arrCopy1 = largeArr.clone();
        int[] arrCopy2 = largeArr.clone();
        
        long startTime = System.currentTimeMillis();
        insertionSort(arrCopy1);
        long endTime = System.currentTimeMillis();
        System.out.println("普通插入排序时间: " + (endTime - startTime) + "ms");
        
        startTime = System.currentTimeMillis();
        binaryInsertionSort(arrCopy2);
        endTime = System.currentTimeMillis();
        System.out.println("二分插入排序时间: " + (endTime - startTime) + "ms");
    }
}

算法特点总结

时间复杂度:

· 最优情况(已排序):O(n)

· 最差情况(逆序):O(n²)

· 平均情况:O(n²)

空间复杂度: O(1) - 原地排序

稳定性: 稳定 - 相等元素的相对位置不变

适用场景:

· 小规模数据排序

· 基本有序的数据

· 作为更复杂算法的子过程

关键点说明

  1. 核心思想:将数组分为已排序和未排序两部分,逐个将未排序元素插入到已排序部分的正确位置。
  2. 内层循环:从后往前比较,同时移动元素,为插入腾出空间。
  3. 插入位置:j + 1 是最终插入位置,因为循环结束时 j 指向的是第一个不大于 key 的元素。
  4. 边界情况:处理空数组或单元素数组时直接返回。

这个实现包含了插入排序的各种变体,可以根据具体需求选择合适的版本。

相关推荐
1024肥宅14 小时前
JavaScript 性能与优化:数据结构和算法
前端·数据结构·算法
用户479492835691514 小时前
XSS、CSRF、CSP、HttpOnly 全扫盲:前端安全不只是后端的事
前端·后端·面试
kaikaile199514 小时前
MATLAB 灰度图像的二维傅里叶变换
算法·计算机视觉·matlab
我家领养了个白胖胖14 小时前
SSE在Spring ai alibaba中同时使用Qwen和DeepSeek模型
java·后端·ai编程
仰泳的熊猫14 小时前
1112 Stucked Keyboard
数据结构·c++·算法·pat考试
roman_日积跬步-终至千里14 小时前
【计算机算法与设计(14)】例题五:最小生成树:Prim算法详细解释:π的含义、更新逻辑和选点原因
算法
让学习成为一种生活方式14 小时前
压缩文件夹下下所有文件成压缩包tar.gz--随笔016
算法
AI科技摆渡14 小时前
GPT-5.2介绍+ 三步对接教程
android·java·gpt
Java编程爱好者14 小时前
做了个Java打包工具,可以双击启动了!
后端
嗷嗷哦润橘_14 小时前
AI Agent学习:MetaGPT项目之RAG
人工智能·python·学习·算法·deepseek