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

一.原理

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

二.过程

因为是个递归的过程,所以一起展示比较方便
在这里插入图片描述

假设一个有序表的元素是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 <h, &sort(l,m) ;sort(m+1,h);并合并\\ \end{cases} sort(l,h)={l=h,l<h,sort(l,m);sort(m+1,h);

三.代码

#include <stdio.h>
#include <stdlib.h>

#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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

康娜喵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值