• 归并排序


    归并排序

    什么是Merge(归并/合并)?

    归并:把两个或多个已经有序的序列合并成一个

    首先先定义一个更大的数组

    接下来可以分别设定指针指向数组的第一个元素

    再来就是把指向合并的散装数组里的元素进行对比。。谁小谁进大数组

    只剩下一个子表未合并时,可以将该表中剩余元素全部加到总表

    “2路”归并

    两个或多个已经有序的序列合并成一个

    “2路”归并——每选出一个小的元素需对比关键字1次

    “4路”归并

    每选出一个小的元素需要对比关键字3次。

    结论:m路归并,每选出一个元素需要对比关键字m-1次

    归并排序(手算模拟)

    在内部排序中一般采用2路归并

    第一躺的归并排序,把相邻的两个部分分别进行2路归并

    第二趟,在对上一趟的归并进行2路归并

    第三趟就可以得到了

    13,27,38,49,65,76,97

    核心操作:把数组内的两个有序序列归并为一个

    代码实现

    int *B = (int *)malloc(n*sizeof(int));	//辅助数组B
    
    //A[low...mid]和A[mid+1...high]各自有序,将两个部分归并
    void Merge(int A[],int low,int mid,int high){
        int i,j,k;
        for(k=low;k<=high;k++)
            B[k] = A[k];					//将A中所有元素复制到B中
        for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){
            if(B[i]<=B[j])
                A[k]=B[i++];				//将较小值复制到A中
            else
                A[k]=B[j++];
        }
        while(i<=mid)	A[k++]=B[i++];
        while(j<=high)	A[k++]=B[j++];
    }
    
    void MergeSort(int A[],int low,int high){
        if(low<high){
            int mid = (low+high)/2;
            MergeSort(A,low,mid);
            MergeSort(A,mid+1,high);
            Merge(A,low,mid,high); 
        }
    }
    

    算法效率分析

    2路归并的“归并树”——形态上就是一棵倒立的二叉树

    [二叉树的第h层最多有2^{h-1}个结点 ]

    [若树高为h,则应满足nle2^{h-1} ]

    [即h-1=lceil log_2n ceil ]

    [结论:n个元素进行2路归并排序,归并趟数=lceil log_2n ceil ]

    [每趟归并时间复杂度为O(n),则算法时间复杂度为O(nlog_2n) ]

    [空间复杂度=O(n),来自辅助数组B ]

    归并算法是稳定的。自己操作。

    知识回顾

  • 相关阅读:
    转换流--OutputStreamWriter类与InputStreamReader类
    Android getResources的作用和须要注意点
    sqlit使用要点之引入libsqlite3.dylib
    C语言文件操作之fgets()
    5款伊思儷超媒體繁体游戏 中文简体补丁
    memcpy的使用方法总结
    开发人员改变世界的初心
    expect
    HDU 1061 N^N (n的n次方的最后一位)
    linux杂谈(二十):apache服务配置
  • 原文地址:https://www.cnblogs.com/jev-0987/p/13322187.html
Copyright © 2020-2023  润新知