归并排序
归并排序,基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。为了让这二组数据有序,可以将A,B组各自再分成二组,依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。
归并排序有两种实现方法:自底向上和自顶向下
自底向上的方法,效率高,但是可读性较差
void mergeSort_nonRecursively(int data[], int length)
{
if (data == NULL || length <= 1)
return;
int *result = (int *)malloc(sizeof(int) * length);
if (result == NULL)
return;
int left, right;
int left_index, right_index;
int step;
for (step = 1; step < length; step *= 2)
{
left = 0;
right = left + step;
left_index = right_index = 0;
int i = 0;
while ((right + right_index) < length)
{
while (left_index < step && right_index < step && ((right + right_index) < length))
{
if (data[left + left_index] < data[right + right_index])
{
result[i ++] = data[left + left_index];
++ left_index;
}
else
{
result[i ++] = data[right + right_index];
++ right_index;
}
}
while (left_index < step)
{
result[i ++] = data[left + left_index];
++ left_index;
}
while (right_index < step && ((right + right_index) < length))
{
result[i ++] = data[right + right_index];
++ right_index;
}
left += step * 2;
right += step * 2;
left_index = 0;
right_index = 0;
}
memcpy(data, result, i * sizeof(int));
}
free(result);
}
自顶向下的方法,其实也就是递归的方法,可读性较好,但效率比非递归的要差些
void mergeSort(int data[], int first, int last, int result[])
{
if (data == NULL || first < 0 || first >= last || result == NULL)
return;
int mid = (first + last) / 2;
mergeSort(data, first, mid, result);
mergeSort(data, mid + 1, last, result);
int left_index = first;
int right_index = mid + 1;
int res_index = 0;
while (left_index <= mid && right_index <= last)
{
if (data[left_index] > data[right_index]) //<升序,>降序
result[res_index ++] = data[left_index ++];
else
result[res_index ++] = data[right_index ++];
}
while (left_index <= mid)
result[res_index ++] = data[left_index ++];
while (right_index <= last)
result[res_index ++] = data[right_index ++];
int i = 0;
for (; i < res_index; i++)
data[first + i] = result[i];
}