1.在讲归并排序之前,我们先复习一下数据结构的基础知识
1.数据元素是数据的基本单位,一个数据元素可以是一个不可分割的原子项,也可由多个数据项组成。
2. 数据的逻辑结构主要可分为3种:线性结构(定义数据元素之间是线性关系),树结构(定义数据元素(结点)之间是层次关系),图结构(则通过图形顶点与边构成的一种结构)。
3.算法的5个基本特性:有穷性,确定性,可行性,有输入,有输出。
4.算法应满足的5个目标:正确性,健壮性,高时间效率性(根据执行算法的时间来判断程序的执行效率),高空间性(根据执行算法占用的空间,来判断程序的执行效率) ,可读性。
5.算法的优劣主要从时间代价和空间代价来判断:
时间复杂度关系: O(1)<O(log2^n)<O(n)<O(nlog2^n)<O(n^2)<O(n^3)<O(2^n),时间复杂度越小代表该算法执行的效率高,反之亦然,我们在解决的问题当中,不要选择for循环暴力破解,通过那种方式虽然能解决问题,但是占用的时间太多,我们应该通过别的方式去解决,用空间换时间 用时间换空间都是在不停的更替来使用,目的就是为了追求程序的最优解,就就是算法的魅力所在吧。
空间复杂程度我在这里就不一一讲解了。
2.接下来我们步入今天的正题,归并排序:
归并排序的思想是:分而治之,分通俗的讲就是将问题分成一个个小的问题,然后通过递归的方式求解,让每的一个元素按照规则出到栈顶;治是归并排序的最重要一步,将分的阶段得到的结果整理放在一起。归并排序的时间复杂度是:nlog2^n
简单的图示:
3.下面就是归并排序的代码实现:
/**
* Created with IntelliJ IDEA.
*
* @Author: chenxiky
* @Date: 2022/02/16/0:14
* @Description: 归并排序
*/
public class MergetSort {
public static void main(String[] args) {
int arr[] = {8,4,5,7,1,3,6,2};
// 归并排序需要一个额外的空间
int temp[] = new int[arr.length];
mergeSort(arr,0,arr.length-1,temp);
System.out.println("归并排序="+ Arrays.toString(arr));
}
// 分+合方法
public static void mergeSort(int[]arr,int left,int right
,int[] temp){
if (left < right){
int mid = (left + right)/2; // 中间的索引
// 向左递归进行分解
mergeSort(arr, left, mid, temp);
// 向右递归进行分解
mergeSort(arr, mid+1, right, temp);
//合并
merge(arr,left,mid,right,temp);
}
}
/**
* 合并的方法
* @param arr 原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void merge(int[] arr,int left,int mid,
int right,int[] temp){
// 计算进行了多少次归并
System.out.println("xxxx");
int i = left; // 初始化i,左边有序序列的初始索引
int j = mid+1; // 初始化j,右边有序序列的初始索引
int t = 0; //指向temp数组的当前索引
// 第一步
// 先把左右两边(有序)的数据按照规则填充到temp数组
// 直到左右两边的有序序列,有一边处理完毕为止
while (i <= mid && j <= right){
// 如果左边有序序列的当前元素 小于等于右边有序序列的当前元素
// 即将左边的当前元素拷贝到temp数组
// t++;i++; +1操作
if (arr[i] <= arr[j]){
temp[t] = arr[i];
t++; //
i++;
} else { // 反之将右边的有序序列的当前元素,填充到temp
temp[t] = arr[j];
t++;
j++;
}
}
//第二步
//把有剩余的数据的一边的数据依次全部填充到temp
while (i <= mid){ //左边的有序序列还有剩余的元素,就全填充到temp
temp[t] = arr[i];
t++;
i++;
}
while (j <= right){ //右边的有序序列还有剩余的元素,就全填充到temp
temp[t] = arr[j];
t++;
j++;
}
//第三步
//将temp数组的元素拷贝到arr
// 注意,并不是每次到拷贝所有的
t =0;
int tempLeft = left;
// 第一次合并时tempLeft=0,right = 3;
while (tempLeft <= right){
arr[tempLeft] = temp[t];
t++;
tempLeft++;
}
}
}
文中若有错的地方,请大家多多见谅。如果大家觉得我的内容有收获可以点击关注哦,同时也可以关注我的公众号: 晨溪