目录
前言
到了这里就是最后一个常见的比较排序了,归并排序也是和快速排序一样的重要,当然也很常见,不多说了一起进入归并排序的世界吧!
一、什么是归并排序
归并排序
是建立在归并操作上的一种有效的排序算法
,
该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
二、使用代码实现
public class Merge{
public static void mergrSort(int[] array){
mergeSortInternal(array,0, array.length - 1);
}
private static void mergeSortInternal(int[] array, int left, int right) {
if(left >= right)return;//递归结束条件
int mid = left + (right - left) / 2;
mergeSortInternal(array,left,mid);//左边
mergeSortInternal(array,mid + 1,right);//右边
merge(array,left,mid,right);//合并
}
private static void merge(int[] array,int left,int mid,int right){
int[] tmp = new int[right - left + 1];//合并两个有序数组
int k = 0;
int s1 = left;
int s2 = mid + 1;
while(s1 <= mid && s2 <= right){
if(array[s1] <= array[s2]){//没有等于就是不稳定的,没有等号就是稳定的排序
tmp[k ++] = array[s1 ++];
}else{
tmp[k ++] = array[s2++];
}
}
while(s1 <= mid){
tmp[k ++] = array[s1 ++];
}
while(s2 <= right){
tmp[k ++] = array[s2 ++];
}
for (int i = 0; i < k; i++) {
array[i + left] = tmp[i];//把合并的数再次赋值给原数组
}
}
三、时间复杂度,空间复杂度和稳定性
时间复杂度:O(N*logN) 也可以类似想象成一颗二叉树时间复杂度是树的高度O(logN)*序列个数N
空间复杂度:O(N) 申请的所有数据数组
稳定性:稳定 挨个进行交换的 如果比较的时候去掉等号就是不稳定的排序了
四、非递归实现归并排序
//非递归的归并排序
public static void mergeSort1(int[] array){
int nums = 1;//每组数的个数
while(nums < array.length){
for (int i = 0; i < array.length; i += 2 * nums) {
int left = i;
int mid = left + nums - 1;
if(mid >= array.length){
mid = array.length - 1;
}
int right = mid + nums;
if(right >= array.length){
right = array.length - 1;
}
//下标确定再进行合并
merge(array,left,mid,right);
}
nums *= 2;
}
}
总结
常见的排序里面稳定的排序有三个:冒泡排序、插入排序还有一个就是今天的归并排序,归并排序相对而言是这三个排序里面稍微难一丢丢的排序,但无疑是最为重要的,所以以后如果需要稳定的排序的话只能从这三个里面选取。到目前为止常见的比较类排序,就介绍完了,后面我将介绍非比较类的排序!