这是合并排序的算法:
注意看起来与发布的代码所实现的完全不同。
注意:这是一种实现归并排序算法的递归方法
--合并排序--
归并排序基于分治法。它需要对列表进行排序和划分
一半以创建两个未排序的列表。然后对这两个未排序的列表进行排序合并得到一个
排序列表。通过不断调用合并排序算法对两个未排序的列表进行排序;我们
最终得到一个已排序的大小为 1 的列表。然后合并两个大小为 1 的列表。
算法:
这是一种分而治之的算法。这工作如下 -
- 将我们必须排序的输入分成中间的两部分。称它为左边部分
和右边的部分。
示例:假设输入是 -10 32 45 -78 91 1 0 -16,那么左边部分将是 -10 32 45 -
78,右边部分是 91 1 0 6。
- 分别对它们进行排序。请注意,这里的排序并不意味着使用其他一些排序
方法。我们递归地使用相同的函数。
- 然后合并两个排序的部分。
输入数组中元素的总数(number_of_elements)。输入
数组(数组[number_of_elements])。然后调用函数 MergeSort() 对输入数组进行排序。
MergeSort() 函数在 [left,right] 范围内对数组进行排序,即从左索引到右索引
包括在内。 Merge() 函数合并两个排序的部分。排序的部分将来自 [left, mid] 和
[中间+1,右]。合并后输出排序后的数组。
MergeSort() 函数:
它将数组、数组的最左边和最右边的索引作为参数进行排序。
数组的中间索引 (mid) 计算为 (left + right)/2。检查是否(左
只有在离开时才需要排序
通过在左侧和右侧再次调用 MergeSort() 函数 MergeSort(array,left,mid)
通过递归调用 MergeSort 函数作为 MergeSort(array,mid + 1, right)。最后合并
使用 Merge 函数的两个数组。
Merge() 函数:
将要合并的数组的最左、中、最右索引为
参数。需要一个临时数组(tempArray[right-left+1])来存储新排序的部分。
临时数组的当前索引位置(pos)初始化为0。左侧索引位置
(lpos) 被初始化为数组的左右索引位置 (rpos) 被初始化为 mid+1。
直到 lpos
if(array[lpos]
rpos位置的数组,然后将array[lpos](数组左侧索引处的值)存储在当前
临时数组的索引位置(pos)并递增位置索引(pos)和left
位置索引(lpos)乘以 1。 tempArray[pos++] = array[lpos++]
否则,将array[rpos](数组右侧索引处的值)存储在的当前索引位置(pos)
临时数组并递增位置索引(pos)和右位置索引(rpos)
1. tempArray[pos++] = array[rpos++]
直到(lpos
tempArray[pos++] = array[lpos++],store array[lpos](数组左侧索引处的值)在
临时数组的当前索引位置(pos)并增加位置索引(pos)
左位置索引 (lpos) 加 1。
直到(rpos
tempArray[pos++] = array[rpos++],store array[rpos](数组右索引处的值)在
临时数组的当前索引位置(pos)并增加位置索引(pos)
右位置索引 (rpos) 加 1。
最后将排序后的数组复制回原数组。
属性:
最佳情况 - 当数组已经排序 O(nlogn)。
最坏情况——当数组以倒序排序时 O(nlogn)。
平均情况 - O(nlogn)。
需要额外的空间,因此数组的空间复杂度为 O(n),链接的空间复杂度为 O(logn)
列表。
这是一个示例代码,来自http://www.thelearningpoint.net/computer-science/arrays-and-sorting-merge-sort--with-c-program-source-code
#include<stdio.h>
/*This is called Forward declaration of function */
void Merge(int * , int , int , int );
/* Logic: This is divide and conquer algorithm. This works as follows.
(1) Divide the input which we have to sort into two parts in the middle. Call it the left part
and right part.
Example: Say the input is -10 32 45 -78 91 1 0 -16 then the left part will be
-10 32 45 -78 and the right part will be 91 1 0 6.
(2) Sort Each of them seperately. Note that here sort does not mean to sort it using some other
method. We already wrote fucntion to sort it. Use the same.
(3) Then merge the two sorted parts.
*/
/*This function Sorts the array in the range [left,right].That is from index left to index right inclusive
*/
void MergeSort(int *array, int left, int right)
{
int mid = (left+right)/2;
/* We have to sort only when left<right because when left=right it is anyhow sorted*/
if(left<right)
{
/* Sort the left part */
MergeSort(array,left,mid);
/* Sort the right part */
MergeSort(array,mid+1,right);
/* Merge the two sorted parts */
Merge(array,left,mid,right);
}
}
/* Merge functions merges the two sorted parts. Sorted parts will be from [left, mid] and [mid+1, right].
*/
void Merge(int *array, int left, int mid, int right)
{
/*We need a Temporary array to store the new sorted part*/
int tempArray[right-left+1];
int pos=0,lpos = left,rpos = mid + 1;
while(lpos <= mid && rpos <= right)
{
if(array[lpos] < array[rpos])
{
tempArray[pos++] = array[lpos++];
}
else
{
tempArray[pos++] = array[rpos++];
}
}
while(lpos <= mid) tempArray[pos++] = array[lpos++];
while(rpos <= right)tempArray[pos++] = array[rpos++];
int iter;
/* Copy back the sorted array to the original array */
for(iter = 0;iter < pos; iter++)
{
array[iter+left] = tempArray[iter];
}
return;
}
int main()
{
int number_of_elements;
scanf("%d",&number_of_elements);
int array[number_of_elements];
int iter;
for(iter = 0;iter < number_of_elements;iter++)
{
scanf("%d",&array[iter]);
}
/* Calling this functions sorts the array */
MergeSort(array,0,number_of_elements-1);
for(iter = 0;iter < number_of_elements;iter++)
{
printf("%d ",array[iter]);
}
printf("\n");
return 0;
}