【数据结构学习记录28】——归并排序

一.原理

我们常见的归并排序,又叫做2路归并排序,相当于是将两个顺序表或链表合在一起的操作。如果我们通过二分法来实现,将个长的顺序表一直二分法一直分到最小的子序列,然后从最小子序列逐步合并成大的表,那么最后这个大表就是有序的了。
所以这是一个递归的过程,时间复杂度为 n l o g 2 n nlog_2n nlog2n

二.过程

因为是个递归的过程,所以一起展示比较方便
【数据结构学习记录28】——归并排序_第1张图片

假设一个有序表的元素是0~n共n+1个元素,其中开始表示l,结束表示h,中间元素表示为m=(l+h)/2
递归表达式可以写为:
s o r t ( l , h ) = { l = h , 递 归 终 止 l < h , s o r t ( l , m ) ; s o r t ( m + 1 , h ) ; 并 合 并 sort(l,h)= \begin{cases} l = h,&递归终止\\ l sort(l,h)={l=h,l<h,sort(l,m);sort(m+1,h);

三.代码

#include 
#include 

#define MAXLEN  100
int temp[MAXLEN] = {0};     //创建一个临时变量数组


int Mergelist(int arry[], int low, int mid,int high)
{
    int tptr, lptr, hptr, i = 0;
    tptr = 0;                           // 临时数组储存下标
    lptr = low;                         // 左序列下标,low<=lptr<=mid
    hptr = mid + 1;                     // 右序列下标,mid+1<=hptr<=high

    while(lptr <= mid && hptr <= high)  // 这三个while就是循环合并两个线性表
    {
        // 将左序列或右序列中,较小的存入临时数组里
        if (arry[lptr] <= arry[hptr])
        {
            temp[tptr] = arry[lptr];
            ++lptr;
        }
        else
        {
            temp[tptr] = arry[hptr];
            ++hptr;
        }
        ++tptr;
    }
    // 检测左序列是否添加完毕
    while(lptr <= mid)
    {
        temp[tptr] = arry[lptr];
        ++lptr;
        ++tptr;
    }
    // 检测右序列是否添加完毕
    while(hptr <= high)
    {
        temp[tptr] = arry[hptr];
        ++hptr;
        ++tptr;
    }
    // 将新序列覆盖原数组
    for (; i < tptr; ++i)
    {
        arry[low+i]=temp[i];
    }
}

int MergeSort(int arry[], int low, int high)
{
    int mid;
    if (low < high) // 可递归部分
    {
        mid = (low + high) / 2;
        MergeSort(arry, low, mid);          // 左序列
        MergeSort(arry, mid+1, high);       // 右序列
        Mergelist(arry, low, mid, high);    // 合并两序列
    }
}


int main()
{
    int a[7] = {6,5,3,7,2,1,4};
    int i;
    MergeSort(a, 0, 6);
    for (i = 0; i < 7; ++i)
    {
        printf("%d ", a[i]);
    }
    return 0;
}

你可能感兴趣的:(数据结构,链表,数据结构,算法,排序算法,归并)