zoukankan      html  css  js  c++  java
  • 归并排序

    下面是归并排序的一些特征:

    • 时间复杂度,最好最坏平均都为:O(nlog2n)
    • 空间复杂度,最好最坏平均都为:O(n)
    • 是否稳定:稳定

    二路归并的时间复杂度为O(nlog2n),多路归并排序在引入败者树后也为O(nlog2n)

    只有在最后一次排序后才每个元素才确定是在最终位置

    归并的含义是将两个或两个以上的有序表组合成一个新的有序表
    2路归并排序的基本思想:将初始待排序的每个元素都看成是一个排好序的子表,然后两两归并,得到n/2个长度为2或1的有序表;再两两归并,如此重复,直到合并为长度为n的有序表为止

    下面是2路归并排序的代码:

    void merge_sort(int arr[], int low, int high)
    {
        if (low < high) {
            int mid = (low+high)/2;         // 从中间划分两个子序列
            merge_sort(arr, low, mid);      // 对左侧子序列进行递归排序
            merge_sort(arr, mid+1, high);   // 对右侧子序列进行递归排序
            merge(arr, low, mid, high);     // 归并
        }//if
    }
    
    /**
    * 合并两个有序表
    */
    void merge(int arr[], int low, int mid, int high)
    {
        // arr[low...mid]与arr[mid+1...high]各自有序,将他们合并
        int i, j, k;
        for (k=low; k<=high; k++)
            arr_bk[k] = arr[k];     // 将arr中的所有元素复制到arr_bk中
        for (i=low, j=mid+1, k=i; i<=mid&&j<=high; k++) {
            if (arr_bk[i] <= arr_bk[j])
                arr[k] = arr_bk[i++];
            else
                arr[k] = arr_bk[j++];
        }//for
        while (i<=mid)  arr[k++] = arr_bk[i++]; // 若第一个表未检测完,复制
        while (j<=high) arr[k++] = arr_bk[j++]; // 若第二个表未检测完,复制
    }
    

    测试代码,可直接复制后编译执行:

    #include <stdio.h>
    #include <stdlib.h>
    
    void show(int arr[], int len);
    void merge_sort(int arr[], int low, int high);
    void merge(int arr[], int low, int mid, int high);
    
    int * arr_bk;   // 辅助排序的数组
    
    int main()
    {
        const int len = 7;
        int arr[len] = {7, 10, 11, 9, -8, 2, 27};
        arr_bk = (int *)malloc(sizeof(int)*len);
        merge_sort(arr, 0, len-1);
        free(arr_bk);
        show(arr, len);
        return 0;
    }
    
    void show(int arr[], int len)
    {
        int i;
        for (i=0; i<len; i++) {
            printf("%4d", arr[i]);
        }
        printf("
    ");
    }
    
    void merge_sort(int arr[], int low, int high)
    {
        if (low < high) {
            int mid = (low+high)/2;         // 从中间划分两个子序列
            merge_sort(arr, low, mid);      // 对左侧子序列进行递归排序
            merge_sort(arr, mid+1, high);   // 对右侧子序列进行递归排序
            merge(arr, low, mid, high);     // 归并
        }//if
    }
    
    /**
    * 合并两个有序表
    */
    void merge(int arr[], int low, int mid, int high)
    {
        // arr[low...mid]与arr[mid+1...high]各自有序,将他们合并
        int i, j, k;
        for (k=low; k<=high; k++)
            arr_bk[k] = arr[k];     // 将arr中的所有元素复制到arr_bk中
        for (i=low, j=mid+1, k=i; i<=mid&&j<=high; k++) {
            if (arr_bk[i] <= arr_bk[j])
                arr[k] = arr_bk[i++];
            else
                arr[k] = arr_bk[j++];
        }//for
        while (i<=mid)  arr[k++] = arr_bk[i++]; // 若第一个表未检测完,复制
        while (j<=high) arr[k++] = arr_bk[j++]; // 若第二个表未检测完,复制
    }
    
  • 相关阅读:
    前端 HTML CSS
    前端部分1:HTML
    异常处理专区:
    IO模型介绍
    协程专区
    线程专区
    操作系统简介专区
    进程专区
    正则表达式专区:
    题解 P2158 【[SDOI2008]仪仗队】
  • 原文地址:https://www.cnblogs.com/qijinzhi/p/merge_sort.html
Copyright © 2011-2022 走看看