• 排序算法学习之归并排序


    1. 归并排序原理:有长度为n的子序列a[n],可以将其看做n个长度为1的子序列,将相邻子序列两两归并后子序列数量减少一半,再对子序列进行两两归并,数量又减少一般,重复直到得到一个长度为n的子序列

    2. 实现归并操作的代码如下:

    /*array[s…m]和array[m+1…t]均已各自有序,合并使得array[s…t]有序*/
    void Merge(int s, int m, int t, int *array)
    {
        int temp[t-s+1];/*设临时数组存放排序后的元素*/
        int i=s, j=m+1, k=0;
        while(i<=m && j<=t)
        {
            if(array[i] < array[j])
                temp[k++] = array[i++];
            else
                temp[k++] = array[j++];
        }
        while(i<=m)
            temp[k++] = array[i++];
        while(j<=t)
            temp[k++] = array[j++];
    
        for(i=s, k=0; i<=t && k<=t-s; i++, k++)    /*将临时数组里的元素复制到原数组*/
        {
            array[i] = temp[k];
        }
    } 

    3. 递归调用代码如下:

    void MSort (int s, int t, int *array)    /*递归调用*/
    {
        if(s == t)
            return ;
        int m = (s+t)/2;    /*设置中间数*/
        MSort(s, m, array);    /*左边序列有序*/
        MSort(m+1, t, array);    /*右边序列有序*/
        Merge(s, m, t, array);    /*将左右有序序列归并*/
    }
    void MergeSort1(int n, int *array)
    {
        MSort(0, n-1, array);
    } 

    4. 归并排序非递归调用的实现

        由于大量引入递归造成时间和空间上性能的损耗,所以我们考虑引入迭代来代替递归,效率必然要高于递归,如下:

    void MergeSort2(int n, int *array)
    {
        int k, i;
        for (k=1; 2*k<n; k *= 2)    /*设置每段待归并的有序序列的长度:1,2,4,8,16……*/
        {
            for (i=0; i+k-1<n; i += 2*k)/*考虑待归并的左右两段序列,[i+k-1]是左序列末尾元素下标*/
            {                /*[end=i+2*k-1]是右序列末尾元素下标,end不应该超过n-1*/
                int end=i+2*k-1;
                if(end > n-1)
                    end = n-1;
                Merge(i, i+k-1, end, array);
            }
        }
    }
  • 相关阅读:
    TCP/IP详解卷:协议 第八章简要总结
    渗透测试1
    以前的实验博客地址,以前使用csdn
    day03---Node (05)
    day03---Vue(04)
    day03---Vue(03)
    day03---ES6入门(02)
    day03---前端开发和前端开发工具(01)
    Docker实战总结
    ETL之Kettle入门
  • 原文地址:https://www.cnblogs.com/lifan/p/3718489.html
Copyright © 2020-2023  润新知