Java实现插入排序算法详解及优化

引言

插入排序(Insertion Sort)是一种简单直观的排序算法。虽然在大数据量下性能不如快速排序和归并排序等高级排序算法,但其在处理小规模数据集和部分有序数据时表现良好。本文将详细讲解如何使用Java实现插入排序算法,并结合图解和实例代码,帮助您全面理解这一基础排序算法。同时,我们还将探讨插入排序的优化方法,以提高其性能。

插入排序算法的原理

插入排序的基本思想是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

算法步骤

  1. 初始状态:从第二个元素开始,将每个元素插入到前面已经排序的子数组中。
  2. 从后向前扫描:对已排序序列,从后向前扫描,找到合适的位置插入当前元素。
  3. 重复上述步骤:直到所有元素均排序完成。

图解插入排序

以下是插入排序的可视化过程:

初始数组: 12, 11, 13, 5, 6
开始插入排序
已排序子数组: 12, 11
插入11到正确位置: 11, 12
已排序子数组: 11, 12, 13
插入13到正确位置: 11, 12, 13
已排序子数组: 11, 12, 13, 5
插入5到正确位置: 5, 11, 12, 13
已排序子数组: 5, 11, 12, 13, 6
插入6到正确位置: 5, 6, 11, 12, 13

Java实现插入排序

public class InsertionSort {
    /**
     * 实现插入排序算法
     * @param arr 待排序的数组
     */
    public static void insertionSort(int[] arr) {
        int n = arr.length;
        // 从第二个元素开始遍历
        for (int i = 1; i < n; ++i) {
            int key = arr[i];
            int j = i - 1;

            // 将 arr[i] 插入到已排序部分
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j = j - 1;
            }
            arr[j + 1] = key;
        }
    }

    public static void main(String[] args) {
        // 初始化数组
        int[] arr = {12, 11, 13, 5, 6};
        // 调用插入排序方法
        insertionSort(arr);
        // 输出排序后的数组
        System.out.println("排序后的数组:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

插入排序的优化方法

二分查找优化

在标准插入排序中,插入元素时需要从后向前逐一比较,找到合适的位置插入。如果我们使用二分查找来确定插入位置,可以减少比较次数,从而提高性能。

public class BinaryInsertionSort {
    /**
     * 使用二分查找实现插入排序算法
     * @param arr 待排序的数组
     */
    public static void binaryInsertionSort(int[] arr) {
        int n = arr.length;
        for (int i = 1; i < n; ++i) {
            int key = arr[i];
            int left = 0;
            int right = i;

            // 使用二分查找找到插入位置
            while (left < right) {
                int mid = (left + right) / 2;
                if (arr[mid] <= key) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }

            // 将大于key的元素向右移动
            for (int j = i; j > left; j--) {
                arr[j] = arr[j - 1];
            }
            arr[left] = key;
        }
    }

    public static void main(String[] args) {
        // 初始化数组
        int[] arr = {12, 11, 13, 5, 6};
        // 调用二分查找插入排序方法
        binaryInsertionSort(arr);
        // 输出排序后的数组
        System.out.println("排序后的数组:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

哨兵优化

使用哨兵优化插入排序可以减少每次插入时的边界检查,从而提高性能。哨兵是一个特殊值,通常设置为数组的第一个元素或一个特殊的极小值。

public class SentinelInsertionSort {
    /**
     * 使用哨兵优化插入排序算法
     * @param arr 待排序的数组
     */
    public static void sentinelInsertionSort(int[] arr) {
        int n = arr.length;
        // 找到数组中的最小值,并将其放在第一个位置作为哨兵
        int minIndex = 0;
        for (int i = 1; i < n; i++) {
            if (arr[i] < arr[minIndex]) {
                minIndex = i;
            }
        }
        // 交换最小值到第一个位置
        int temp = arr[0];
        arr[0] = arr[minIndex];
        arr[minIndex] = temp;

        // 从第二个元素开始排序
        for (int i = 1; i < n; ++i) {
            int key = arr[i];
            int j = i - 1;

            // 由于有哨兵,不需要检查边界
            while (arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = key;
        }
    }

    public static void main(String[] args) {
        // 初始化数组
        int[] arr = {12, 11, 13, 5, 6};
        // 调用哨兵优化插入排序方法
        sentinelInsertionSort(arr);
        // 输出排序后的数组
        System.out.println("排序后的数组:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

结论

通过上述讲解和实例代码,我们详细展示了如何在Java中实现插入排序算法,并结合图解说明了其工作原理。同时,我们探讨了插入排序的优化方法,包括二分查找优化和哨兵优化,以提高其性能。

希望这篇博客对您有所帮助!记得关注、点赞和收藏哦,以便随时查阅更多优质内容!


如果您觉得这篇文章对您有帮助,请关注我的CSDN博客,点赞并收藏这篇文章,您的支持是我持续创作的动力!


  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值