归并排序
归并排序
归并排序有以下三个步骤:
确定数组下标中点mid = l + r >> 1,把数组分为左右两段。
核心点在最后的合二为一,我们定义i、j两个指针代表左右两段的开头,依次比较大小,小的放入tmp数组,如果相等放哪一个都可以,默认放i所代表的数字。
直到一方结束,把另一方剩余的续在tmp数组的后面。
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1000010;
int n;
int q[N],tmp[N];
void merge_sort(int l,int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(l,mid);
merge_sort(mid + 1,r);
//双指针算法实现归并操作
int k = 0,i = l,j = mid + 1;
while(i <= mid && j <= r)
{
if (q[i] <= q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
}
//有一边没有循环完,把剩下的全部续到后面
while(i <= mid) tmp[k++] = q[i++];
while(j <= r) tmp[k++] = q[j++];
for (i = l,j = 0; i <= r;i ++, j ++ ) q[i] = tmp[j];
}
int main(){
scanf("%d",&n);
for (int i = 0; i < n; i ++ ) scanf("%d",&q[i]);
merge_sort(0,n-1);
for (int i = 0; i < n; i ++ ) printf("%d ",q[i]);
return 0;
}
时间复杂度
平均时间复杂度
把n每次除2直到1,需要logn次。即logn层。每层都要扫n次。