程序猿正能量
靠代码行数来衡量开发进度,就像是凭重量来衡量飞机制造的进度。—比尔·盖茨
前言
作为开发人员,尤其是三年以上工作经验的 ,如果整天都是在CRUD,这个时候,你是不是需要憧憬一下35岁之后的生活呢?退休送外卖还是回老家种田呢?因为你除了CRUD,其他你一概不会,所以这个时候,你需要改变一下自己,比如:学习数据结构与算法俗话说的好,算法是程序员的灵魂,只有触及到灵魂深处,你才能看见诗和远方,加油吧,骚年!
一、我们这篇文章讲什么呢?
既然都说了算法是一个程序猿的灵魂,那么我们当然是要冲击一下灵魂了,没错,这篇文章我们将算法:归并排序和快速排序。
二、归并排序
1.什么是归并排序
归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
根据概念和动图,你是否能看明白呢?也许还有点懵吧,其实归并就是借助了分治的思想,把一个大问题拆分成许多个小问题,然后解决小问题,小问题解决了,大问题自然就解决了,这个时候你可能有点疑惑了,刚刚说的这个不就是递归吗?为什么又成分治了呢?这里大家要搞明白一点:分治是一种思想,递归是一种实现技巧
。
也许上面的动图不太好理解,那么请看下图
先将需要排序的数组进行拆解,拆解到只有两个元素二点之后进行排序,然后在合并,如此反复,即可得到一个完全有序的数组。
下面我们就一起来使用分治思想、递归方案来实现归并排序。
## 2.利用递归实现归并排序
package com.liuxing.sort;
import com.liuxing.util.Print;
/**
* @author liuxing007
* @ClassName MergeSort
* @Description 归并排序(Merge Sort)
* 归并排序的核心思想还是蛮简单的。如果要排序一个数组,
* 我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,
* 再将排好序的两部分合并在一起,这样整个数组就都有序了。
*
* 时间复杂度:O(nlogn)
* 空间复杂度:O(n)
* 不是原地排序算法
* @date 2020/9/17 15:04
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = new int[]{
6,4,1,7,2,5,8,3};
int length = arr.length;
System.out.println("排序前数组===========");
Print.print(arr, length);
sort(arr, length);
System.out.println("排序后数组===========");
Print.print(arr, length);
}
/**
* 排序算法
* @param arr 数组
* @param l 数组长度
*/
private static void sort(int[] arr,int l){
sortMerge(arr,0,l-1);
}
/**
* 递归
* @param arr 数组
* @param p 开始位置下表
* @param r 结束位置下表
*/
private static void sortMerge(int[] arr,int p,int r){
if(p >= r){
return ;
}
//分治的下标,这里我采用p到r的中间位置index。
int index = p + (r-p)/2;
//左侧递归
sortMerge(arr,p,index);
//右侧递归
sortMerge(arr, index + 1, r);
merge(arr, p, index,r);
System.out.println("排序后数组===========");
Print.print(arr, length);
}
/**
* 合并计算
* @param arr 原素组
* @param l 左侧数组开始位置下标
* @param index 左侧数组结束位置下标
* @param r 右侧数组结束位置下标
*/
private