Bootstrap

力扣经典题目之912.排序数组(使用希尔排序解决)

今天继续给大家分享一道力扣的做题心得今天这道题目是 912.排序数组

题目链接:912. 排序数组 - 力扣(LeetCode)

题目:给你一个整数数组 nums,请你将该数组升序排列。

你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。

示例 1:        输入:nums = [5,2,3,1]         输出:[1,2,3,5]


1,题目分析

此题不难,单纯考察排序,这里我们使用希尔排序来完成此题,希尔排序是一种基于插入排序的改进算法,它通过比较距离一定间隔的元素来工作,然后逐步减小间隔,直到间隔为1时,整个数组基本有序,最后使用插入排序完成最终排序。话不多说,直接上解题代码。

2,解题思路

class Solution {
    public int[] sortArray(int[] a) {
        int len = a.length;
        int gap = len / 2; // 初始间隔

        while (gap > 0) {
            // 对每个子列表进行插入排序
            for (int i = gap; i < len; i++) {
                int j = i;
                int tmp = a[i];
                // 插入排序,将a[i]插入到前面的有序子列表中
                for (j = i; j >= gap && tmp < a[j - gap]; j -= gap) {
                    a[j] = a[j - gap];
                }
                a[j] = tmp;
            }
            gap /= 2; // 减小间隔
        }
        return a;
    }
}
  1. 初始化间隔

    • int gap = len / 2;:初始间隔设置为数组长度的一半。这个间隔用于确定哪些元素将被比较和交换。
  2. 外层循环

    • while (gap > 0):只要间隔大于0,就继续进行排序。每次循环结束时,间隔减半,直到间隔为1。
  3. 内层循环

    • for (int i = gap; i < len; i++):从间隔gap开始遍历数组。每个元素a[i]将被插入到前面的有序子列表中。
    • int j = i;:初始化一个索引j,用于内层的插入排序。
    • int tmp = a[i];:保存当前元素a[i]的值,用于后续的插入操作。
  4. 插入排序

    • for (j = i; j >= gap && tmp < a[j - gap]; j -= gap):从当前元素a[i]开始,向前比较和移动元素,直到找到合适的位置插入tmp。这里的关键是比较tmpa[j - gap],如果tmp小于a[j - gap],则将a[j - gap]向后移动一个间隔。
    • a[j] = tmp;:将tmp插入到正确的位置。
  5. 减小间隔

    • gap /= 2;:每次外层循环结束时,间隔减半。这使得算法逐步从宏观的调整(大间隔)过渡到微观的调整(小间隔),最终在间隔为1时进行精细的插入排序。

代码难点

  1. 理解希尔排序的原理
    • 希尔排序的关键在于间隔序列的设置。不同的间隔序列会影响算法的性能。在代码中,间隔每次减半,这是一种常见的选择,但不是最优的。例如,可以使用更复杂的间隔序列,如Hibbard序列(1, 3, 7, 15, ...)或Sedgewick序列(1, 5, 19, 41, ...),这些序列可以进一步优化算法的性能。
  2. 插入排序的实现
    • 插入排序部分需要仔细处理索引和条件判断。特别是for (j = i; j >= gap && tmp < a[j - gap]; j -= gap)这个循环,需要确保索引j不会越界,并且正确地将tmp插入到合适的位置。
  3. 性能优化
    • 希尔排序的性能在很大程度上取决于间隔序列的选择。虽然你的实现已经能够正确排序,但通过选择更优的间隔序列,可以进一步提高算法的效率。

总结

        实现了希尔排序算法,能够有效地对数组进行排序。通过逐步减小间隔,算法从宏观调整过渡到微观调整,最终使用插入排序完成排序。理解间隔序列的选择和插入排序的实现是掌握希尔排序的关键。通过选择更优的间隔序列,可以进一步优化算法的性能。

4,总结

        感谢大家的阅读,希望这篇解题心得能为大家带来一些收获,我们共同进步!大家的点赞就是我的动力谢谢大家,还有什么更优解或者问题欢迎大家在评论区讨论分享!

;