排序算法(归并排序)
前言
归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法的一个非常典型的应用。
一、归并
- 对于我这样一个接触排序算法比较晚的人来说,归并排序带给我的不一定是实现排序的结果还有就是对于这样一个比较牛逼的排序的思想的理解。在这其中最重要的就是思想的实现以及理解。
- 归并归并,重点就是在于它的归与并的理解,什么时候是归什么时候是并。在这里的归中的实现的是树的思考,我们将一个数组的所有元素(数字)分成一个个的单一的数字例如下图:
在树的最底层,也就是最后的3–2,我们在这个时候使用的就是并的思想,将3–2按照顺序排列交换其中的位置,得到我们需要的单个的排序的序列2–3,然后将上层的3–2替换为我们得到的正确的序列2–3.这样就完成了最底一层的归并实现,再由此向上传递即可。
- 还有一个问题,那么就是我们每次的并的操作使用的是新的数组,定义一个可以将原来数组替换长度得子序列的数组长度得数组,将我们的排序的新的序列数组存入到,在这里就等于是合并两个有序的子序列数组到新的数组中,完成后替换原来数组中的元素即可。看下图
通过这样的一系列操作完成的是可能是树的一两个根节点数组的有序,依次向上递归实现就可以将原来数组完成替换,即完成归并排序操作。
二、代码
}
/**归并排序*/
public static void mergeSort(int[] arr,int l,int r){
if (l >= r){return;}
int mid = (l+r)/2;
mergeSort(arr,l,mid);
mergeSort(arr,mid+1,r);
/**合并两个区间--排序合并*/
mergeTwoIntervals(arr,l,mid,mid+1,r);
}
public static void mergeTwoIntervals(int[] arr, int l1, int r1, int l2, int r2) {
int[] temp = new int[r2 - l1 + 1];
int i = l1,j = l2,k = 0;
while (i <= r1 || j <= r2){
if ((j > r2) || (i <= r1 && arr[i] <= arr[j])){
// temp[k++] = arr[i++];
temp[k] = arr[i];
k++;
i++;
}else {
temp[k] = arr[j];
k++;
j++;
}
}
for(int p = l1;p<=r2;p++){
arr[p] = temp[p - l1];
}
}
总结
利用树的思想,并通过均分的方式将数组分为一个完全二叉树,这样得到的树的深度最优,类似于二叉树的后序遍历对整个数组进行遍历操作,在遍历的一个步骤就正好是归并的并的过程。
这是很明显的分治思想,将一个排序的大问题分为两个数的比较,当多个的两个数的比较完成就可以得到一个个的有序的数组,再将这样的有序数组进行合并就可以得到一个根片段的结果。