最近阅读啦归并排序相关资料,结合自己的理解整理并编程实现进行测试验证。
归并排序利用啦分而治之的思想,将复杂问题转变为简单问题而后进行处理,然后对处理的结果在进行处理,最后得到需要的结果。
归并排序算法的为代码描述如下:
已知array[start..middle-1] and array[middle..end]都已经排好序啦
Merge(array, start, middle, end):
Create left[..] = array[start..middle-1];
right[..] = array[middle..end];
i = j =0;
for k <– start up to end
if (left[i] <=right[j] and i < middle – start )or j > end – middle
array[k] = left[i++];
else
array[k] = left[j++];
MergeSort(array, start, end):
if start < end
middle = (start + end)/2;
MergeSort(array, start, middle);
MergeSort(array, middle+1, end);
Merge(array, start, middle+1, end);
上述描述为增序排序,降序排序只需要将left[i] <=right[j]改变为left[i] >=right[j]即可。
将上述伪代码用C语言实现,增减type参数以便实现增序排序和将需排序。为了便于清晰了解递归,对于每一步都进行啦打印,显示每次归并的结果。代码如下:
#include <stdio.h>
typedef enum
{
NON_DECREASE,
NON_INCREASE
}t_sort;
void output_arry(int *array, int n)
{
int i;
for(i = 0; i < n; i++)
{
printf ("%d ", array[i]);
}
printf ("\n");
}
int recursive = 1;
void merge(int *array, int start, int middle, int end, t_sort type)
{
int i,j,k;
int *left = (int*)malloc(sizeof(int) * (middle - start));
int *right = (int*)malloc(sizeof(int) * (end - middle + 1));
for(i = 0; i < middle - start; i++)
left[i] = array[start + i];
printf ("Left array: ");
output_arry(left, middle - start);
for(i = 0; i < end - middle + 1; i++)
right[i] = array[middle + i];
printf ("Right array: ");
output_arry(right, end - middle + 1);
for(k = start, i = 0, j = 0; k <= end; k++)
{
if(type == NON_DECREASE)
{
if((left[i] <= right[j] && i < middle - start) || j > end - middle)
{
array[k] = left[i++];
printf ("L: %d\n", array[k]);
}
else
{
array[k] = right[j++];
printf ("R: %d\n", array[k]);
}
}
else
{
if((left[i] >= right[j] && i < middle - start) || j > end - middle)
{
array[k] = left[i++];
printf ("L: %d\n", array[k]);
}
else
{
array[k] = right[j++];
printf ("R: %d\n", array[k]);
}
}
}
printf ("--%d Merged array: ", recursive);
output_arry(array + start, end - start + 1);
free(left);
free(right);
}
void merge_sort(int *array, int start, int end, t_sort type)
{
int middle;
if(start < end)
{
middle = (start + end)/2;
merge_sort(array, start, middle, type);
merge_sort(array, middle+1, end , type);
merge(array, start, middle+1, end, type);
recursive ++;
}
}
int
main(void)
{
int arry[] = {10,7,8,4,5,2,1,6,3,8};
printf ("The original data is: ");
output_arry(arry, sizeof(arry)/sizeof(int));
merge_sort(arry, 0, sizeof(arry)/sizeof(int) - 1, NON_DECREASE);
//merge_sort(arry, 0, sizeof(arry)/sizeof(int) - 1, NON_INCREASE);
printf ("The sorted data is: ");
output_arry(arry, sizeof(arry)/sizeof(int));
return 0;
}
测试增序排序结果如下:
The original data is: 10 7 8 4 5 2 1 6 3 8
Left array: 10
Right array: 7
R: 7
L: 10
--1 Merged array: 7 10
Left array: 7 10
Right array: 8
L: 7
R: 8
L: 10
--2 Merged array: 7 8 10
Left array: 4
Right array: 5
L: 4
R: 5
--3 Merged array: 4 5
Left array: 7 8 10
Right array: 4 5
R: 4
R: 5
L: 7
L: 8
L: 10
--4 Merged array: 4 5 7 8 10
Left array: 2
Right array: 1
R: 1
L: 2
--5 Merged array: 1 2
Left array: 1 2
Right array: 6
L: 1
L: 2
R: 6
--6 Merged array: 1 2 6
Left array: 3
Right array: 8
L: 3
R: 8
--7 Merged array: 3 8
Left array: 1 2 6
Right array: 3 8
L: 1
L: 2
R: 3
L: 6
R: 8
--8 Merged array: 1 2 3 6 8
Left array: 4 5 7 8 10
Right array: 1 2 3 6 8
R: 1
R: 2
R: 3
L: 4
L: 5
R: 6
L: 7
L: 8
R: 8
L: 10
--9 Merged array: 1 2 3 4 5 6 7 8 8 10
The sorted data is: 1 2 3 4 5 6 7 8 8 10
测试降序排序结果如下:
The original data is: 10 7 8 4 5 2 1 6 3 8
Left array: 10
Right array: 7
L: 10
R: 7
--1 Merged array: 10 7
Left array: 10 7
Right array: 8
L: 10
R: 8
L: 7
--2 Merged array: 10 8 7
Left array: 4
Right array: 5
R: 5
L: 4
--3 Merged array: 5 4
Left array: 10 8 7
Right array: 5 4
L: 10
L: 8
L: 7
R: 5
R: 4
--4 Merged array: 10 8 7 5 4
Left array: 2
Right array: 1
L: 2
R: 1
--5 Merged array: 2 1
Left array: 2 1
Right array: 6
R: 6
L: 2
L: 1
--6 Merged array: 6 2 1
Left array: 3
Right array: 8
R: 8
L: 3
--7 Merged array: 8 3
Left array: 6 2 1
Right array: 8 3
R: 8
L: 6
R: 3
L: 2
L: 1
--8 Merged array: 8 6 3 2 1
Left array: 10 8 7 5 4
Right array: 8 6 3 2 1
L: 10
L: 8
R: 8
L: 7
R: 6
L: 5
L: 4
R: 3
R: 2
R: 1
--9 Merged array: 10 8 8 7 6 5 4 3 2 1
The sorted data is: 10 8 8 7 6 5 4 3 2 1
归并排序的时间复杂度为O(nlgn),从上面的测试结果可以看出相同的数在排序前后,其相对位置没有改变,因此它是一种稳定的排序。