归并排序

归并排序原理很简单,是将两个或两个以上的有序表组合成一个新的有序表。

 

假设初始序列有n个记录,则可看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2或1(怎么?为什么有1的可能,想想知道吧,如果是奇数序列呢)的有序子序列;再两两归并,.........如此重复,直至得到一个长度为n的有序序列为止,这种排序称为2-路归并排序。如果还不明白。。。就看看如下图:

 

49   38     65     97      76     13     27

 |      |        |        |        |         |       |

 -------        --------         --------        |

     |                |                  |            |

38   49     65     97      13      76    27    一趟归并排序后

  |      |       |        |         |         |      |

   -------------------           --------------

              |                               |

38   49     65      97      13     27     76   二趟归并排序后

  |      |       |        |          |       |        |

  --------------------------------------------

                           |

 13   27    38      49       65     76     97  三趟归并排序

 

代码贴上,从下面代码可以看出,实现归并排序需要和待排纪录等数量的辅助空间,其时间复杂度为O(nlog2n)。与快速排序和堆排序相比,归并排序最大的特点是:它是稳定排序,但是一般的情况下。很少利用2-路归并排序进行内部排序。

 

/****************************************************************
    Function: sort_Merge
        Date: 2010-06-14
      Author: Robbie
 Description: 合并两个序列
       Input: INT *piData  待排序的数列
              INT iNum   数列个数
      Output: None
      Return: None
      Modify:
*****************************************************************/
STATIC VOID sort_Merge(IN INT *piData, IN INT iLow, IN INT iMid, IN INT iHigh)
{
    INT i, j, k;
    INT *piTmp = (INT *)malloc((UINT)(iHigh - iLow + 1) * sizeof(INT));
    if (NULL == piTmp)
    {
        return;
    }

    for (i = iLow, j = iMid + 1, k = 0; (i <= iMid) && (j <= iHigh); k++)
    {
        if (piData[i] < piData[j]) /* 将数从小到大放入piTmp中 */
        {
            piTmp[k] = piData[i++];
        }
        else
        {
            piTmp[k] = piData[j++];
        }
    }

    while (i <= iMid) /* 将第一个序列剩余的数拷贝到piTmp */
    {
        piTmp[k++] = piData[i++];
    }

    if (j <= iHigh)   /* 将第二个序列剩余的数拷贝到piTmp */
    {
        piTmp[k++] = piData[j++];
    }

    for (i = iLow; i <= iHigh; i++) /* 将排好序的数列拷贝回原数列 */
    {
        piData[i] = piTmp[i - iLow];
    }
       
    free(piTmp);
   
    return;
}


/****************************************************************
    Function: sort_MergeRecur
        Date: 2010-06-14
      Author: Robbie
 Description: 归并排序
       Input: INT *piData  待排序的数列
              INT iNum   数列个数
      Output: None
      Return: None
      Modify:
*****************************************************************/
STATIC VOID sort_MergeRecur(IN INT *piData, IN INT iFirst, IN INT iLast)
{
    INT iMid = 0;

    if (iFirst < iLast)
    {
        iMid = (iFirst + iLast)/2;

        sort_MergeRecur(piData, iFirst, iMid);
        sort_MergeRecur(piData, iMid + 1, iLast);
        sort_Merge(piData, iFirst, iMid, iLast);
    }
       
    return;
}

/****************************************************************
    Function: SORT_Merge
        Date: 2010-06-14
      Author: Robbie
 Description: 归并排序
       Input: INT *piData  待排序的数列
              INT iNum   数列个数
      Output: None
      Return: None
      Modify:
*****************************************************************/
VOID SORT_Merge(IN INT *piData, IN INT iNum)
{
    if ((iNum <= 1) || (NULL == piData))
    {
        return;
    }
   
    sort_MergeRecur(piData, 0, iNum -1);

    return;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

robbie1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值