归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
分类 | 排序算法 |
---|---|
数据结构 | 数组 |
最差时间复杂度 | Θ(nlog n) |
最优时间复杂度 | Θ(n) |
平均时间复杂度 | Θ(nlog n) |
最差空间复杂度 | Θ(n) |
最佳算法 | 有时是 |
归并操作
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
算法描述
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针达到序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
#include<iostream>
using namespace std;
int time = 0;
void merge(int array[], int low, int mid, int high)
{
int k;
int *temp = (int *) malloc((high-low+1) * sizeof(int)); //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
int begin1 = low;
int end1 = mid;
int begin2 = mid + 1;
int end2 = high;
for (k = 0; begin1 <= end1 && begin2 <= end2; ++k) //比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
if(array[begin1]<=array[begin2])
temp[k] = array[begin1++];
else
{
temp[k] = array[begin2++];
time = time + mid + 1 - begin1;
}
if(begin1 <= end1) //若第一个序列有剩余,直接拷贝出来粘到合并序列尾
memcpy(temp+k, array+begin1, (end1-begin1+1)*sizeof(int));
if(begin2 <= end2) //若第二个序列有剩余,直接拷贝出来粘到合并序列尾
memcpy(temp+k, array+begin2, (end2-begin2+1)*sizeof(int));
memcpy(array+low, temp, (high-low+1)*sizeof(int));//将排序好的序列拷贝回数组中
free(temp);
}
void merge_sort(int array[], int first, int last)
{
int mid = 0;
if(first<last)
{
mid = (first+last)/2;
merge_sort(array, first, mid);
merge_sort(array, mid+1,last);
merge(array,first,mid,last);
}
}
int main()
{
int n,i;
int *array = new int[500000];
while(cin>>n && n!=0)
{
for (i=0;i<n;i++)
cin>>array[i];
time=0;
merge_sort(array,0,n-1);
cout<<time<<endl;
}
delete []array;
return 0;
}