详解归并排序

1.归并排序

归并排序使用了分治递归的思想,将具有n的元素的无序序列划分为n个每个含有一个元素的序列,再将n个有序序列采用二路归并等合并方法进行合并排序成一个有序的序列。

2.归并实现步骤

2.1.划分划分左半部分后,合并排序左半部分

        2.1.1递归划分左半部分

如图:

从中间划分,之后再从左半部分划分,递归划分左边部分

 

 ...... 直至划分为一个子序列

         2.1.2合并左半部分的子序列,后面同理

 

2.1.划分右半部分后,合并排序右半部分

同左半部分

3.代码实现

//归并排序,二路归并排序
void mergeSort(int arr[], int length) {
    int* assistArr = (int*)malloc((length) * (sizeof(int)));
    if (!assistArr) {
        printf("内存分配失败!");
    }
    mSort(arr,assistArr, 0, length - 1);
    free(assistArr);
}
void mSort(int arr[],int* assistArr, int low, int high) {
   
    if (low < high) {
        //选出中间点
        int mid = (low + high) / 2;
        //左递归划分
        mSort(arr,assistArr, low, mid);
        //右递归划分
        mSort(arr,assistArr, mid + 1, high);
        //子序列排序
        merge(arr,assistArr, low, high, mid);
    }
}

void merge(int arr[],int* assistArr , int low, int high, int mid) {

    int i=0;  //i指针用来标记low所指的位置
    int j = 0;  //j指针用来标识high指针所指的位置
    int k = 0;  //k指针用来标识原数组的位置

    //将待排序的元素拷贝到辅助数组中
    for ( i = low; i <= high; i++) {
        assistArr[i] = arr[i];
    }
       //令 i 指针指向 low , j 指针指向 high ,k指向i  
    for ( i=low, j = mid+1,  k = i; i <= mid && j <= high; k++) {
        if (assistArr[i] <= assistArr[j]) {    //将待排序的两个序列的首元素比较
            arr[k] = assistArr[i++];     //选出小的直接插回原数组中,令指向小元素指针++
        }
        else {
            arr[k] = assistArr[j++];   
        }
    }
    while (i <= mid) {   //如果两个序列左边的元素个数多于右边的,直接将多的赋值回原数组(此时两个序列分别都是有序的,所以可以直接复制回去)
        arr[k++] = assistArr[i++];
    }
    while (j <= high) {         //右边元素多余左边的情况
        arr[k++] = assistArr[j++];
    }

}

4.测试

因为在排序两个相同的值有特殊处理,所以归并排序是一个稳定的算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值