zoukankan      html  css  js  c++  java
  • 浅谈数据结构-归并排序

    归并算法采用分治法,利用二叉树的概念来实现排序算法,建立在递归合并操作的基础上算法。通过将数组分组到两个序列,排序,然后在归并排序,进而实现算法。归并排序算法就是利用归并的思想实现的排序算法。

    一、算法思想

    数组序列{16, 7, 13, 10, 9, 15, 3, 2, 5, 8, 12, 1, 11, 4, 6, 14},利用一定的交换排序,得到有序的小序列后,进行两两合并排序后再合并,最终获得一个有序的数组。从形状上开像极了一棵倒置的完全二叉树

        它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两再归并,得到|n/2|(|x|表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,......,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。

    归并排序其实要做两件事:

    (1)“分解”——将序列每次折半划分

    (2)“合并”——将划分后的序列段两两合并后排序

    image

    二、代码

    //归并排序
    inline void SortAlgorithm::MergeSort(int *pLarray,int *pRarray,int start ,int length)
    {
        //因为是二叉树概念,长度为一般,跨度合并的话就是步长
        int i = 1;
        int j;
        while(i <= length - 2*start +1)
        {
            Merge(pLarray,pRarray,i,i+start-1,i+2*start-1);   //两两合并
            i = i+2*start;
        }
        if (i < length-start+1)   //归并最后两个序列,此处为length,注意点
        {
            Merge(pLarray,pRarray,i,i+start-1,length);
        }
        else
            for(j = i;j<= length;j++)    //如果剩下最后序列
                pRarray[j] = pLarray[j];
    }
    inline void SortAlgorithm::Merge(int *pLaray,int *pRarray,int start,int length1,int length2)
    {
        int j,k ,l;
        for (k = start,j = length1+1;start<=length1&&j<=length2;k++)   //夸组将相应的元素进行合并
        {
            //左边的数小于右边数,将小的数填入目标数组
            if (pLaray[start] < pLaray[j])
            {
                pRarray[k] = pLaray[start];
                start++;
            }
            else
            {
                pRarray[k] = pLaray[j];
                j++;
            }
        }
        if (start <=length1)  //将剩余的填入到目标数组中
        {
            for (l = 0;l<=length1-start;l++)
            {
                pRarray[l+k] = pLaray[start+l];
            }
        }
        if (j <= length2)
        {
            for(l = 0; l <= length2 - j; l++)
            {
                pRarray[l+k] = pLaray[j+l];      //将剩余的sr[j...n]复制到tr 
            }
        }
    }
    //归并排序
    void SortAlgorithm::MergeSort(pSqlList pList)
    {
        //申请空间,存储合并后的有序数组
        int *Array = new int[10];
        
        memset(Array,0,pList->length);
        int k =1;
        while(k < pList->length)
        {
            //合并序列,从序列大小为1开始,然后2,4,8,
            MergeSort(pList->SqlArray,Array,k,pList->length-1);
            k = k*2;
            MergeSort(Array,pList->SqlArray,k,pList->length-1);
            k = k*2;
            for (int  i =0;i<pList->length;i++)
            {
                printf("%d	",Array[i]);
            }
            PrintSqlList(pList);
            printf("
    ");
        }
    }

    三、代码分析

    image

    image

    image

    程序结果如上图,分析则为下面两幅图

    步骤:

    1、首先是两两进行交换合并,形成初步有序小序列

    2、然后再讲刚才的两两有序序列进行再次合并,形成四组,其中关键代码在Merge函数中。

    3、程序一定注意数组的起止点,还有数组长度等问题,比如,本数组是9个数据,最后是8个元素和1个元素合并,后面调用merge时,为length。

  • 相关阅读:
    PAT(A) 1065. A+B and C (64bit) (20)
    PAT(A) 1046. Shortest Distance (20)
    PAT(A) 1042. Shuffling Machine (20)
    PAT(A) 1009. Product of Polynomials (25)
    PAT(A) 1002. A+B for Polynomials (25)
    win10开始菜单打不开怎么办?
    排序
    C语言文件读写操作总结
    NO.3 4 章 模拟、算法初步
    POJ2104 K-th Number(归并树)
  • 原文地址:https://www.cnblogs.com/polly333/p/4817582.html
Copyright © 2011-2022 走看看