归并排序原理

1.概念

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

2.步骤

  1. 将一个序列从中间位置分成两个序列;
  2. 在将这两个子序列按照第一步继续二分下去;
  3. 直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再两两合并成一个有序序列。

上图:在这里插入图片描述

3.python代码实现

def merge(a, b):
    c = []
    h = j = 0
    while j < len(a) and h < len(b):
        if a[j] < b[h]:
            c.append(a[j])
            j += 1
        else:
            c.append(b[h])
            h += 1

    if j == len(a):
        for i in b[h:]:
            c.append(i)
    else:
        for i in a[j:]:
            c.append(i)

    return c


def merge_sort(s):
    if len(s) <= 1:
        return s
    middle = len(s)//2
    left = merge_sort(s[:middle])
    right = merge_sort(s[middle:])
    return merge(left, right)


if __name__ == '__main__':
    s=[2,8,9,1,3]
    print (merge_sort(s))

4.算法描述

时间复杂度
当有n个记录时,需进行⌈logn⌉轮归并排序,每一轮归并,其估计值比较次数不超过n,元素移动次数都是n,因此,归并排序的时间复杂度为O(nlogn)。

空间复杂度
用容器实现归并排序时,需要和待排序记录个数相等的存储空间,所以空间复杂度为O(n)。

该算法是稳定排序。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
归并排序是一种基于分治法的排序算法,它的基本思路是将待排序的序列不断地划分成更小的子序列,直到每个子序列只有一个元素,然后再将这些子序列两两合并,直到最终得到一个有序的序列。 具体的归并排序算法步骤如下: 1. 将待排序序列不断地二分划分,直到每个子序列只有一个元素。 2. 将相邻的两个子序列进行合并,合并时比较两个子序列的元素大小,将较小的元素放在新的序列中。 3. 重复步骤2,直到所有的子序列都合并成一个有序的序列。 归并排序的关键在于合并操作,合并操作的实现可以使用一个辅助数组来存储合并后的结果。具体的合并操作步骤如下: 1. 创建一个与待排序序列大小相同的辅助数组。 2. 将待排序序列的两个子序列分别赋值给辅助数组的两个子序列。 3. 使用两个指针分别指向辅助数组的两个子序列的起始位置,比较两个指针所指向的元素大小,将较小的元素放入原始序列中,并将指针向后移动一位。 4. 重复步骤3,直到其中一个子序列的元素全部放入原始序列中。 5. 将另一个子序列中剩余的元素依次放入原始序列中。 下面是C++实现归并排序的代码示例: ```cpp #include <iostream> using namespace std; // 合并两个有序子序列 void merge(int arr[], int left, int mid, int right) { int i = left; // 左子序列的起始位置 int j = mid + 1; // 右子序列的起始位置 int k = 0; // 辅助数组的起始位置 int* temp = new int[right - left + 1]; // 辅助数组 // 比较两个子序列的元素大小,将较小的元素放入辅助数组中 while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } // 将剩余的元素放入辅助数组中 while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } // 将辅助数组的元素复制回原始序列 for (int m = 0; m < k; m++) { arr[left + m] = temp[m]; } delete[] temp; } // 归并排序 void mergeSort(int arr[], int left, int right) { if (left < right) { int mid = (left + right) / 2; mergeSort(arr, left, mid); // 对左子序列进行归并排序 mergeSort(arr, mid + 1, right); // 对右子序列进行归并排序 merge(arr, left, mid, right); // 合并两个有序子序列 } } int main() { int arr[] = {5, 2, 8, 3, 1, 6}; int n = sizeof(arr) / sizeof(arr[0]); mergeSort(arr, 0, n - 1); cout << "Sorted array: "; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值