1.什么是归并排序?
1.1 算法原理
归并排序是创建在归并操作上的一种有效排序算法(稳定),速度仅次于快速排序。
1.2.基本思想
归并排序其实就是分治思想,分治模式在每一层递归上有2个步骤
-
分 :将n个元素分为含n/2个元素的2个子序列(若n>1,则一直切分,直到n=1)
-
治 : 用合并排序法分别对两个子序列进行递归的排序,然后合并已经排序好的子序列。
-
可以理解为从上到下,再从下到上,分–排序–合。
算法步骤(如何合并2个子序列):
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
- 重复步骤 3 直到某一指针达到序列尾;
- 将另一序列剩下的所有元素直接复制到合并序列尾。
3.复杂度分析
平均时间复杂度:O(nlogn)
最好时间复杂度:O(n)
最差时间复杂度:O(nlogn)
空间复杂度:O(n)
排序方式:就地排序
稳定性:稳定
4.Java实现
public class Solution{
public static void merge_sort(int[] arr) {
merge_sort_recursive(arr, 0, arr.length-1);
}
public void merge_sort_recursive(int[] arr,int left,int right){
if(left>=right)return;
int mid=(left+right)/2;
merge_sort_recursive(arr,left,mid);
merge_sort_recursive(arr,mid+1,right);
meger(arr,left,mid,right);
}
public void meger(int [] arr,int left,int mid,int right){
int[] result=new int [arr.length];//创建临时数组,用于存储归并后的元素,临时数组的大小和原数组一样大。
int start1=left,end1=mid,start2=mid+1,end2=right;
int k=left; //创建游标
while(start1<=end1&&start2<=end2){ //将两个子序列进行排序,并且存储到临时数组中
if(arr[start1]<arr[start2]){
result[k++]=arr[start1++];
}else{
result[k++]=arr[start2++];
}
}
while(start1<=end1){
result[k++]=arr[start1++];
}
while(start2<=end2){
result[k++]=arr[start2++];
}
for(k=left;k<=right;k++){ //将临时数组中的元素再复制到数组中
arr[k]=result[k]; //游标k的作用在此处,用于复制
}
}
}
}
感谢您的阅读,如有疑问请在下方评论区提出,作者期待和您一起讨论学习,您的点赞和评论是对作者最大的支持!