算法:合并排序

作者: 小码侠 | 来源:发表于2018-10-28 22:48 被阅读2次

合并排序是一种基于分而治之技术排序的方法,最坏的情况下复杂度为O(n log n)。

合并排序首先将数组分成相等的一半,然后已排序方式组合他们。

原理解析

声明一个未排序的数组

image

将数组分成两段

image

再将两个数组分成两半

image

一直分下去,直到不能再分为止。

image

现在,我们以完全相同的方式将它们组合在一起。请注意这些列表的颜色代码。

我们首先比较每个列表的元素,然后以排序的方式将它们组合到另一个列表中。我们看到14和33处于排序位置。我们比较27和10并且在2个值的目标列表中我们首先放置10个,然后是27.我们改变19和35的顺序,而顺序地放置42和44。

image

继续组合

image

在最终合并以后,列表如下:

image

代码实现

GO

package main

import (
    "fmt"
)

func main() {
    numbers := []int{14, 33, 27, 10, 35, 19, 42, 44}
    fmt.Printf("%v\n", numbers)
    numbers = MergeSort(numbers)
    fmt.Printf("%v\n", numbers)
}
func MergeSort(numbers []int) []int {
    length := len(numbers)
    //数组不可再分
    if length <= 1 {
        return numbers
    }
    //评分两个数组。
    mid := length / 2
    //递归进行,持续分割
    array1, array2 := MergeSort(numbers[0:mid]), MergeSort(numbers[mid:length])
    //分组完成,合并分组数据
    return Merge(array1, array2)
}
func Merge(array1, array2 []int) []int {
    len1 := len(array1)
    len2 := len(array2)
    //获取数据长度
    lmax := len1
    if lmax < len2 {
        lmax = len2
    }
    if lmax < 1 {
        return array1
    }
    var ret []int
    //需要合并数组元素下标
    index1 := 0
    index2 := 0
    for true {
        if index2 >= len2 && index1 >= len1 {
            //所有数据排序完毕,退出循环
            break
        }
        if index1 < len1 && index2 < len2 {
            // 两个数组 同时存在元素
            if array1[index1] < array2[index2] {
                ret = append(ret, array1[index1])
                index1++
            } else {
                ret = append(ret, array2[index2])
                index2++
            }
        } else if index1 < len1 {
            //array1 单独存在元素
            ret = append(ret, array1[index1])
            index1++
        } else if index2 < len2 {
            //array2 单独存在元素
            ret = append(ret, array2[index2])
            index2++
        }
    }
    return ret
}

Python

numbers = [14, 33, 27, 10, 35, 19, 42, 44]


def merge_sort(lo, hi):
    if lo >= hi:
        return
    else:
        mid = int((lo + hi) / 2)
        #print(lo, mid, hi, "\n")
        merge_sort(lo, mid)
        merge_sort(mid + 1, hi)
        merge(lo, mid, hi)


def merge(lo, mid, hi):
    loIndex = lo
    hiIndex = mid

    merged = []
    while True:
        if loIndex < mid and hiIndex <= hi:
            if numbers[loIndex] < numbers[hiIndex]:
                merged.append(numbers[loIndex])
                loIndex += 1
            else:
                merged.append(numbers[hiIndex])
                hiIndex += 1

        elif loIndex < mid:
            # array1 单独存在元素
            merged.append(numbers[loIndex])
            loIndex += 1
        elif hiIndex <= hi:
            # array2 单独存在元素
            merged.append(numbers[hiIndex])
            hiIndex += 1

        if loIndex >= mid and hiIndex > hi:
            break

    for i in range(0, len(merged), 1):
        numbers[i + lo] = merged[i]


print("排序前:", numbers)
merge_sort(0, len(numbers) - 1)
print("排序后:", numbers)

#排序前: [14, 33, 27, 10, 35, 19, 42, 44]
#排序后: [10, 14, 19, 33, 27, 35, 42, 44]

长按二维码关注我们

相关文章

  • Java实现每日一道算法面试题(20):leecode23 合并

    1.算法题目 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 2.算法思路 算法思...

  • ARTS第五周2020620

    Algorithm 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例...

  • 合并排序

    合并排序 算法介绍: 合并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法 的一个非常典型的应用。合...

  • Python 算法大全

    这个库涵盖了多种算法和数据结构的介绍,比如: 排序算法(冒泡排序、希尔排序、插入排序、桶排序、合并排序、快速排序、...

  • 合并K个排序链表【LeetCode:23】

    题目: 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入: ...

  • Swift - LeetCode - 合并K个排序链表

    题目 合并K个排序链表 问题: 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 解题思路:...

  • LeetCode:合并K个排序链表

    合并K个排序链表(困难) 题目叙述: 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例...

  • Timsort详解

    原理介绍 TimSort是结合了合并排序(合并排序)和插入排序(插入排序)而得出的排序算法,它在现实中有很好的效率...

  • 23. 合并K个排序链表

    23.合并K个排序链表 合并k个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 输入:[ 1-...

  • 合并排序和快速排序

    归属:分治法 算法复杂度: 合并排序:θ(nlogn)快速排序:一般是O(nlogn) 稳定性:合并排序稳定,快速...

网友评论

    本文标题:算法:合并排序

    本文链接:https://www.haomeiwen.com/subject/onfvtqtx.html