归并排序

第一种方法:merge时,新建一个R-L+1长的新数组,把合并后的结果放到新数组,再复制回原数组。

 1 #include<iostream>
 2 using namespace std;
 3 int A[5] = { 5,9,7,2,1 };
 4 void merge(int *A, int l, int m, int r)
 5 {
 6     int *B = new int[r - l + 1];
 7     int i = l;
 8     int j = m + 1;
 9     int k = 0;
10     while (i <= m && j <= r)
11     {
12         if (A[i] < A[j])
13         {
14             B[k++] = A[i++];
15         }
16         else
17         {
18             B[k++] = A[j++];
19         }
20     }
21     while (i <= m)
22     {
23         B[k++] = A[i++];
24     }
25     while (j <= r)
26     {
27         B[k++] = A[j++];
28     }
29     int x = 0;
30     while (x <= k)
31     {
32         A[l++] = B[x++];
33     }
34     cout << "----------merge()---------" << endl;
35     cout << "l:" << l << endl;
36     cout << "m:" << m << endl;
37     cout << "r:" << r << endl;
38     for (int i = 0; i < 5; ++i)
39     {
40         cout << A[i] << " ";
41     }
42     cout << endl;
43     free(B);
44 }
45 void mergeSort(int *A, int l, int r)
46 {
47     if (l < r)//递归出口,当分解当序列中只有一个元素后就不再进行分解了
48     {
49         int m = (l + r) / 2;
50         mergeSort(A, l, m);
51         mergeSort(A, m + 1, r);
52         merge(A, l, m, r);
53     }
54 }
55 
56 int main22()
57 {
58 
59     mergeSort(A, 0, 4);
60     for (int i = 0; i < 5; ++i)
61     {
62         cout << A[i] << endl;
63     }
64     system("pause");
65     return 0;
66 }

第二种方法:merge时新建左右两个数组,把原数组的左右两半复制到这个新数组里,在两个新数组的基础上把合并结果覆盖到原数组上。

#include<iostream>
using namespace std;
void merge(int * A, int l, int m, int r)
{
    int *B = new int[m - l + 1];
    int *C = new int[r-m];

    for (int i = 0; i < m - l + 1; ++i)
    {
        B[i] = A[i+l];
    }
    for (int i = 0; i < r-m; ++i)
    {
        C[i] = A[i+m+1];
    }
    int i = 0;
    int j = 0;
    int k = l;
    while (i < m - l+1 &&j<r-m)
    {
        if (B[i] < C[j])
        {
            A[k++] = B[i++];
        }
        else
        {
            A[k++] = C[j++];
        }
    }
    while (i < m - l+1)
    {
        A[k++] = B[i++];
    }
    while (j < r-m)
    {
        A[k++] = C[j++];
    }
    free(B);
    free(C);
}
void mergeSort(int * A,int l,int r)
{
    if (l < r)
    {
        int m = (l + r) / 2;
        mergeSort(A, l, m);
        mergeSort(A,m+1,r);
        merge(A,l,m,r);
    }
}
int main()
{
    int A[5] = { 5,2,1,7,3 };
    mergeSort(A,0,4);
    for (int i = 0; i < 5; ++i)
    {
        cout << A[i] << endl;
    }
    system("pause");
    return 0;
}

第三种方法:在全局开辟一个原数组的拷贝,合并时在这个全局数组里倒腾,优点:不用每次都开辟新的数组,但是数组复制的这一步还是不能避免。

#include<iostream>
#include<time.h>
using namespace std;
int *a;
int *b;
int n;
void merge(int *a,int s,int m,int e,int *b)
{
    //a[s,m]和a[m+1,e]肯定是有序的
    //将数组a的局部a[s,m]和a[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回a[s,m]
    int i = s;
    int j = m+1;
    int k = 0;
    while (i <= m && j <= e)
    {
        if (a[i] < a[j])
        {
            b[k++] = a[i++];
        }
        else
        {
            b[k++] = a[j++];
        }
    }
    while (i <= m)
    {
        b[k++] = a[i++];
    }
    while (j <= e)
    {
        b[k++] = a[j++];
    }
    for (int i = 0; i < e - s + 1; ++i)
    {
        a[s + i] = b[i];
    }
}
void mergeSort(int *a, int s,int e,int *b)
{
    if (s < e)
    {
        int m = (s + e) / 2;
        mergeSort(a,s,m,b);
        mergeSort(a,m+1,e,b);
        merge(a,s,m,e,b);
    }
}
void insertSort(int * a)
{
    for (int j = 1; j < n; ++j)
    {
        int key = a[j];
        int i = j - 1;
        while (i >= 0 && a[i] > key)
        {
            a[i + 1] = a[i];
            i--;
        }
        a[i + 1] = key;
    }
}


int main()
{
    //int n;
    cout << "输入数组元素个数:" << endl;
    cin >> n;
    a1 = (int *)malloc(sizeof(int)*n);
    srand((unsigned)time(NULL));
    for (int i = 0; i < n; ++i)
    {
        a1[i] = (rand() % 100);
    }
    b = (int *)malloc(sizeof(int)*n);
    for (int i = 0; i < n; ++i)
    {
        b[i] = a[i];
    }
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/knmxx/p/9940943.html