分治法之归并排序

思路:

  1. 将待排序数组分成两个子数组,计算中间位置mid。
  2. 对左半部分进行递归排序,得到一个有序的子数组。
  3. 对右半部分进行递归排序,得到另一个有序的子数组。
  4. 合并两个有序的子数组,得到一个完整的有序数组。

示例图:

代码:

#include<iostream>
using namespace std;


void merge(int arr[], int start1, int end1, int start2, int end2){

    //左边数组的长度
    int n1 = start1 - end1 + 1;

    //右边数组的长度
    int n2 = start2 - end2 + 1;

    //定义左右两个子数组
    int* arr_left = new int[n1];
    int* arr_right = new int[n1]; 

    //从原数组中复制左边的数组
    for(int i = 0; i < n1; i++) left_arr[i] = arr[start1 + i];
  
    //从原数组中复制右边的数组
    for(int i = 0; i < n2; i++) right_arr[i] = arr[start2 + i];

    //指向左右两个数组首元素的指针
    int left = 0, right = 0;

    //临时数组,存放合并后的数组
    int p = start1;

    //左右两个数组不为空
    while(left < n1 && right < n2){

        //左边数组的元素小于右边数组的元素
        if(arr_left[left] < arr_right[right]){

            //将左边数组的值存入临时数组,同时两指针右移一位
            arr[p++] = arr_left[left++];
    }

    //右边的数组为空
    while(left < n1){
     
         //将左边数组的值存入临时数组,同时两指针右移一位
         arr[p++] = arr_left[left++];

    }

    //左边的数组为空
    while(right < n2){

         //将右边数组的值存入临时数组,同时两指针右移一位
         arr[p++] = arr_right[right++];
    }

}


mergesort(int arr[], int start, int end){

//当数组长度小于等于1时直接返回数组
if(start >= end){

    return;

}

//取数组的中间位置
int mid = (start + end) / 2;

//对左边的数组进行递归排序
mergesort(arr, start, mid);

//对右边的数组进行递归排序
mergesort(arr,mid + 1, end);

//递归的的两个数组进行合并
merge(arr, start, mid, mid + 1, end);

}

int main(){


    //定义数组
    int arr[] = {8, 1, 3, 2, 9, 7, 6, 5, 4};

    //数组长度
    int n = sizeof(arr) / sizeof(arr[0]);

    //调用递归数组
    mergesort(arr, 0, n - 1);

    //打印数组
    for(int i = 0; i < n; i++){

        cout << arr[i] << " ";

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值