**原理**

 1. 将长的排序序列分割成单个子序列(最小子序列是单个数字)
 2. 采用递归思路,逐个先递归左边(排好序),其次递归右边(排好序)
 
 3. 递归遍历如下图

图片描述


 4.代码结果见下图

clipboard.png

//归并排序 

#include <iostream>
using namespace std;

//拆分,把r —— >r1
void merge_sort(int r[], int r1[], int first, int end);

//将一个从中间分开 ,两边排好序的数组r,交叉进入r1数组,完成排序
void merge(int r[], int r1[], int first, int mid, int end);

int main()
{
    int r[100], r1[100], n;
    while (cin >> n, n != EOF)
    {
        for (int i = 0; i < n; i++)
        {
            cin >> r[i];
        }
        merge_sort(r, r1, 0, n-1);
        for (int i = 0; i < n; i++)
        {
            cout << r[i]<<" ";
        }
    }
}

//因为分治法,导致数组,变成多个小段
//first——r数组的开头
//mid——r数组的分界位置
//end——r数组的末尾

void merge(int r1[], int r[], int first, int mid, int end)
{
    //定义,循环递增变量
    int i = first;
    int j = mid + 1;
    //k 记录r1位置
    int k = first;
    //直到把某一半数组遍历完,跳出循环
    while (i <= mid&&j <= end)
    {
        //比较两边子序列的数值,将较小的——>r1
        if (r1[i] <= r1[j])
        {
            r[k++] = r1[i++];
        }
        else
        {
            r[k++] = r1[j++];
        }
    }
    //判断那边的子序列还有剩余,将剩余全部——>r1
    if (i <= mid)
    {
        while (i <= mid)
        {
            r[k++] = r1[i++];
        }
    }
    else
    {
        while (j <= end)
        {
            r[k++] = r1[j++];
        }
    }
    //注意这一步的理解
    for (int i = first; i <= end; i++)
    {
        r1[i] = r[i];
    }
}

void merge_sort(int r[], int r1[], int first, int end)
{
    //出口——>拆分到只剩下,每边只剩下一个值
    if (first == end)
    {
        r1[first] = r[first];
    }
    else
    {
        //递归拆分
        int mid = (first + end) / 2;
        merge_sort(r, r1, first, mid);
        merge_sort(r, r1, mid + 1, end);
        //合并,节约空间——r1——>r中倒
        merge(r1, r, first, mid, end);
    }
}

Light
11 声望0 粉丝