算法之合并排序(mergeSort)

  合并排序算法在结构上是递归的,采用分治策略:就是将原有的问题划分为 n 个规模较小但结构与原问题相似的子问题,递归地解决这些子问题,然后合并其结果,就得到原问题的解。

  合并排序的模式一般如下:

  1.分解:将 n 个元素分解为各含 n/2 个元素的两个序列;

  2.解决:用分治排序法对两个子序列递归地排序;

  3.合并:合并两个已排好序的子序列得到排序结果。

  在对子序列递归的过程中,当子序列元素数为1时,递归结束。

  合并排序算法的时间复杂度为O(nlgn)

 void merge(int* a, int p, int q, int r)
{
int i = ;
int j = ;
int k = ;
int n1 = q - p + ;
int n2 = r - q;
int* L = (int*)malloc((n1 + ) * sizeof(int));
int* R = (int*)malloc((n2 + ) * sizeof(int));
for(i = ; i < n1; i++)
{
*(L + i) = a[p + i];
}
*(L + n1) = INT_MAX; //插入序列末标志 for(i = ; i < n2; i++)
{
*(R + i) = a[q + i + ];
}
*(R + n2) = INT_MAX; //插入序列末标志 i = ;
j = ;
k = ;
for(k = p; k < r + ;k++)
{
if(*(L + i) > *(R + j))
{
*(a + k) = *(R + j);
j++;
}
else
{
*(a + k) = *(L + i);
i++;
}
}
} void mergeSort(int* a, int p, int r)
{
int q = ;
if(p < r)
{
q = (r + p) / ;
mergeSort(a, p, q);
mergeSort(a, q + , r);
merge(a, p, q, r);
}
}

注:1. mergeSort(int* a, int p, int r) 和 merge(int* a, int p, int q, int r)中的形参 p, q, r 都是序列 a 的索引,其中子序列 L = (a[p] ~ a[q]),其长度为 q - p + 1;子序列 R = (a[q + 1] ~ a[r]),其长度为 r - (q + 1) - 1 即 r - q;

   2.在上述代码中都插入了 序列标志数,这个数默认为∞,但在实际应用中,该数有可能会出现在应用序列中,merge函数可改为如下:

 void merge(int* array, int p, int q, int r)
{
int i = ;
int j = ;
int k = ;
int n1 = q - p + ;
int n2 = r - q;
int* L = (int*)malloc((n1) * sizeof(int));
int* R = (int*)malloc((n2) * sizeof(int));
for(i = ; i < n1; i++)
{
*(L + i) = array[p + i];
}
//*(L + n1) = INT_MAX; for(j = ; j < n2; j++)
{
*(R + j) = array[q + j + ];
}
//*(R + n2) = INT_MAX; i = ;
j = ;
k = ;
for(k = p; k < r + ;k++)
{
if(i > (n1 - ))
{
*(array + k) = *(R + j);
j++;
}
else if(j > (n2 - ))
{
*(array + k) = *(L + i);
i++;
}
else
{
if(*(L + i) > *(R + j))
{
*(array + k) = *(R + j);
j++;
}
else
{
*(array + k) = *(L + i);
i++;
}
}
}
}
上一篇:Centos6.9安装vsftpd并配置多用户的方法


下一篇:go语言变量