文章目录
- 归并排序
- 1.归并排序的复杂度分析
- 2.细节解释
- 3.归并排序动图演示
- 3(1) 我们的拆分过程如下↓
- 4.code↓
- 洛谷P1177【模板】排序
- 数据规模与约定
- code(归并排序)↓
- code(sort排序【快速排序】)
- 完结撒花( ̄▽ ̄) /
归并排序
归并排序
(merge sort)是高效的
基于比较的稳定排序
算法。
1.归并排序的复杂度分析
归并排序的时间复杂度
为 O ( n l o g n ) O(nlogn) O(nlogn)
归并排序的空间复杂度
是 O ( n ) O(n) O(n)(这是因为他不是原地排序算法
)
2.细节解释
( l + r ) > > 1 = ( l + r ) ÷ 2 1 = ( l + r ) ÷ 2 (l+r)>>1=(l+r)\div 2^{1}=(l+r)\div 2 (l+r)>>1=(l+r)÷21=(l+r)÷2;
3.归并排序动图演示
在这里我们是默认
了它以中间为节点
,分别
排成了从大到小
的两个序列
的
这是因为有merge_sort(q,l,mid),merge_sort(q,mid+1,r)
来不断
进行拆分
的原因
3(1) 我们的拆分过程如下↓
这里的动图演示
,先执行了
下方代码
int k=0,i=l,j=mid+1;//i表示左半边的开始,j表示右半边的开始,k表示合并的个数while(i<=mid&&j<=r){//对半分后,mid是i的终点,r是j的终点if(q[i]<=q[j]) tmp[k++]=q[i++];//不断将tmp填充,i++else tmp[k++]=q[j++];//else 等同于if(q[i]>q[j]) }
当q[i]
和q[j]
已经超过了
他们的终点
(i
的终点
是mid
,j
的终点
是r
),那么就执行下方代码
while(i<=mid) tmp[k++]=q[i++];//将i没有填充完的继续进行填充while(j<=r) tmp[k++]=q[j++];//将j没有填充完的继续进行填充
执行上方代码
时一定有一个值(i or j
) 是已经超过了他们的终点的,不然不会退出循环,所以不用考虑大小关系
执行上方代码
是为了将剩下的可以填充的数
给填充进tmp数组
里,以此来保证没有遗漏
动图演示↓
4.code↓
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int n,a[maxn] ,tmp[maxn];
void merge_sort(int q[],int l,int r){//要排序的数组,左边界,有边界if(l>=r) return;//不满足要求int mid=(l+r)>>1;//m是l+r的中间值,(l+r)>>1=(l+r)/(2^{1})=(l+r)/2;merge_sort(q,l,mid),merge_sort(q,mid+1,r);//不断将它进行拆分,然后归并int k=0,i=l,j=mid+1;//i表示左半边的开始,j表示右半边的开始,k表示合并的个数while(i<=mid&&j<=r){//对半分后,mid是i的终点,r是j的终点if(q[i]<=q[j]) tmp[k++]=q[i++];//不断将tmp填充,i++else tmp[k++]=q[j++];//else 等同于if(q[i]>q[j]) }while(i<=mid) tmp[k++]=q[i++];//将i没有填充完的继续进行填充while(j<=r) tmp[k++]=q[j++];//将j没有填充完的继续进行填充for(int i=l,j=0;i<=r;i++,j++){q[i]=tmp[j];//将已经排好序的(tmp[l]~tmp[r])给赋值到q数组}
}
int main(){ios::sync_with_stdio(false);//加速cincin.tie(0),cout.tie(0);cin>>n;for(int i=0;i<n;i++){cin>>a[i];//输入数列}merge_sort(a,0,n-1);//进行排序for(int i=0;i<n;i++){cout<<a[i]<<" ";//进行排好序了的进行输出}return 0;
}
洛谷P1177【模板】排序
题意:将读入的 N N N个数从小到大
排序后输出
数据规模与约定
对于 20 % 20\% 20% 的数据,有 1 ≤ N ≤ 1 0 3 1 \leq N \leq 10^3 1≤N≤103;
对于 100 % 100\% 100% 的数据,有 1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^5 1≤N≤105, 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109。
code(归并排序)↓
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int n,a[maxn] ,tmp[maxn];
void merge_sort(int q[],int l,int r){if(l>=r) return;int mid=(l+r)>>1;merge_sort(q,l,mid),merge_sort(q,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(int i=l,j=0;i<=r;i++,j++){q[i]=tmp[j];}
}
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n;for(int i=0;i<n;i++){cin>>a[i];}merge_sort(a,0,n-1);for(int i=0;i<n;i++){cout<<a[i]<<" ";}return 0;
}
code(sort排序【快速排序】)
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,a[maxn]={};
int main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];sort(a,a+1+n);for(int i=1;i<=n;i++) cout<<a[i]<<" ";return 0;
}