二路归并排序

#include <iostream>
using namespace std;
void MergeSort(int a[], int n);
void MergePass(int a[], int length, int n);
void Merge(int a[], int min, int mid, int max);
int main()
{
    int a[10];
    for (int i = 0; i < 10; i++)
        cin >> a[i];
    MergeSort(a, 10);
    for (int i = 0; i < 10; i++)
        cout << a[i] << " ";
    return 0;
}
/*此函数实现二路归并排序*/
void MergeSort(int a[], int n) // n是数组长度
{
    int length = 1; // length是子序列的长度
    for (length = 1; length < n; length *= 2)
        MergePass(a, length, n);
}
/*此函数实现一趟子序列长度为length的二路归并排序*/
void MergePass(int a[], int length, int n)
{
    int i = 0;
    for (i = 0; i + 2 * length - 1 < n; i += 2 * length) //对相邻的长度为length的子序列归并
        Merge(a, i, i + length - 1, i + 2 * length - 1);
    /*上方这个循环结束有2种情况:
    第一种:剩下的所有元素是一个序列,那就不用处理了
    第二种:剩下的元素在2个序列里,前一个序列长度为length,后面的长度长度比length短*/
    if (i + length -1< n) //第二种情况,把这2个子序列归并了
    {
        Merge(a, i, i + length - 1, n - 1);
    }
}
/*此函数实现合并2个相邻子序列*/
void Merge(int a[], int min, int mid, int max)
{
    int *temp = new int[max - min + 1];
    int i = min, j = mid + 1, k = 0; // i和j分别是2个子序列的下标,k是temp的下标
    while (i <= mid && j <= max)     //当2个子表都没有扫描完的时候
    {
        if (a[i] <= a[j])
        {
            temp[k] = a[i];
            i++;
            k++;
        }
        else
        {
            temp[k] = a[j];
            j++;
            k++;
        }
    }
    while (i <= mid)
    {
        temp[k] = a[i];
        i++;
        k++;
    }
    while (j <= max)
    {
        temp[k] = a[j];
        j++;
        k++;
    }
    for (i = min, k = 0; i <= max; i++, k++) //把temp数组里的值复制回数组a[]
    {
        a[i] = temp[k];
    }
    delete[] temp;
}

 

posted @ 2022-04-07 13:18  越来越懒了  阅读(52)  评论(0)    收藏  举报