1.归并排序递归
从中间将一整个数组分成两个数组,假设这两个数组已经完成了排序,那么设立一个新的数组,取两个数组各自第一个数据进行比较,那个数组的数据小就放入这个新建的数组,然后再重新在这个数组取数,再和另外一个数组原来取的数进行比较,那个小那个就放入这个新建的数组,直到有一个数组的数被取完,那么另外一个数组的全部数据都将依次放入新建的组,再将新建的数组的数据mencpy到原数组中就完成了排序,
那么要怎么使两边的数组都是有序的呢???
请看VCR
通过以上的递归方式实现排序,当递归的数只剩两个那么这两边就是有序的那么这两边就能进行比较排序,进行完比较排序了之后就返回这个数组,然后其它的数组也一样返回,所有返回完毕便实现了数组的排序。
代码实现如下
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void _MergeSort(int* a,int* temp,int left,int right)
{
if (left >= right)
{
return;
}
int mid = (right + left) / 2;
int begin1 = left;
int begin2 = mid+1;
int end1 = mid;
int end2 = right;
_MergeSort(a, temp, begin1, end1);
_MergeSort(a, temp, begin2, end2);
int i = begin1;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1]<a[begin2])
{
temp[i++] = a[begin1++];
}
else
{
temp[i++] = a[begin2++];
}
}
while (begin1 <= end1)
{
temp[i++] = a[begin1++];
}
while (begin2<=end2)
{
temp[i++] = a[begin2++];
}
memcpy(a + left, temp + left, sizeof(int) * (right - left + 1));
}
void MergeSort(int* a, int n)
{
int left = 0, right = n - 1;
int* temp = (int*)malloc(sizeof(n));
_MergeSort(a, temp, left, right);
}
2.归并排序非递归
归并排序非递归就是先将数组两个两个进行排序,再四个四个进行,再八个八个进行。直到数组被分为两组排序那么就结束。
代码实现如下
void MergeSortNonR(int* a, int n)
{
int* temp = (int*)malloc(sizeof(int) * n);
if (temp == NULL)
{
perror("malloc");
return;
}
int gap = 1;
while (gap < n)
{
for (int i = 0; i < n; i = i + gap * 2)
{
int begin1 = i, end1 = i + gap - 1;
int begin2 = i + gap, end2 = i + 2 * gap - 1;
if (end1 >= n-1)
{
break;
}
if (end2 >= n-1)
{
end2 = n - 1;
}
int j = begin1;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
{
temp[j++] = a[begin1++];
}
else
{
temp[j++] = a[begin2++];
}
}
while (begin1 <= end1)
{
temp[j++] = a[begin1++];
}
while (begin2 <= end2)
{
temp[j++] = a[begin2++];
}
memcpy(a + i, temp + i, sizeof(int) * (end2 - i + 1));//没有搞清楚begin1和i,begin1会变
}
gap = gap * 2;
}
}
但是排序时要注意,因为访问位置是2的倍数增加,当数组个数不是二的倍数时就会造成越界访问,所以在上述代码中增加了如下代码。
if (end1 >= n-1)
{
break;
}
if (end2 >= n-1)
{
end2 = n - 1;
}