数组排序简介-希尔排序(Shell Sort)

基本思想

        将整个数组切按照一定的间隔取值划分为若干个子数组,每个子数组分别进行插入排序。然后逐渐缩小间隔进行下一轮划分子数组和对子数组进行插入排序。直至最后一轮排序间隔为1,对整个数组进行插入排序。

算法步骤

假设数组的元素个数为 n个,则归并排序的算法步骤如下:

  1. 分解过程:先递归地将当前数组平均分成两半,直到子数组长度为1。
    1. 找到数组中心位置 midmid,从中心位置将数组分成左右两个子数组 left_nums、right_nums。
    2. 对左右两个子数组 left_nums、right_nums 分别进行递归分解。
    3. 最终将数组分解为 n个长度均为 1 的有序子数组。
  2. 归并过程:从长度为 1 的有序子数组开始,依次将有序数组两两合并,直到合并成一个长度为 n 的有序数组。
    1. 使用数组变量 nums 存放合并后的有序数组。
    2. 使用两个指针 left_i、right_i 分别指向两个有序子数组 left_nums、right_nums的开始位置。
    3. 比较两个指针指向的元素,将两个有序子数组中较小元素依次存入到结果数组 nums 中,并将指针移动到下一位置。
    4. 重复步骤 33,直到某一指针到达子数组末尾。
    5. 将另一个子数组中的剩余元素存入到结果数组 nums 中。
    6. 返回合并后的有序数组 nums。

我们以 [0,5,7,3,1,6,8,4] 为例,演示一下归并排序算法的整个步骤。

适用场景

        希尔排序是对直接插入排序的一种优化,可以用于大型的数组,希尔排序比插入排序和选择排序要快的多,并且数组越大,优势越大。

排序稳定性

        因为在两个有序子数组的归并过程中,如果两个有序数组中出现相等元素,merge(left_nums, right_nums): 算法能够使前一个数组中那个相等元素先被复制,从而确保这两个元素的相对顺序不发生改变。因此,归并排序算法是一种 稳定排序算法

代码实现(golang)

func shellSort(arr []int) {
    n := len(arr)
    gap := n / 2
    for gap > 0 {
        for i := gap; i < n; i++ {
            temp := arr[i]
            j := i
            for j >= gap && arr[j-gap] > temp {
                arr[j] = arr[j-gap]
                j -= gap
            }
            arr[j] = temp
        }
        gap /= 2
    }
}

func main() {
    arr := []int{9, 7, 5, 11, 12, 2, 14, 3, 10, 6}
    fmt.Println("原始数组:", arr)
    shellSort(arr)
    fmt.Println("排序后数组:", arr)
}

猜你喜欢

转载自blog.csdn.net/Runing_WoNiu/article/details/143323871
今日推荐