课程名称:笑傲Java面试 剖析大厂高频面试真题 秒变offer收割机
课程章节:第3章 白板篇之数据结构和算法
主讲老师:求老仙
课程内容:
面试数据结构和算法
课程收获:
归并排序,怎么写,和注意点?如何写一个递归程序?
问题0)如何写一个递归程序
分而治之,一般使用递归算法,递归代码和具体思考流程,相关联?
1,思考具体的递归操作:常规一遍操作(递归前的操作)和重复常规操作
2,递归代码:常规操作(递归前的操作)和递减操作(就是重复常规操作)(体现在函数的参数递减上)
3,递归代码分三步:递归基,常规操作(递归前和递归后),递减操作(就是具体思考流程重复操作,体现在函数的参数递减)
问题1)归并排序,怎么写,和注意点?
对数组进行排序,使用递归方式实现归并排序:
归并排序的思想:中间拆分-》处理-》合并
实现流程:每次除以2进行拆分,拆分到最后一个元素时候,再进行有序合并
* 归并排序,使用递归
*/
public static void main(String[] args) {
Integer[] aa = {6,3,21,23,4,7,8,0,9};
mergeSort001 mer = new mergeSort001();
mer.mergeSort(aa,0,aa.length);
for (Integer i : aa) {
System.out.println(i);
}
}
/**
* 注意3点:
*
* 合并流程,传入的是[)区间。
* 注意:
* 1,循环不变量,传入的参数意义要一致。左边是开区间,右边是闭区间
* 2,做比较的时候,不要用l<=r,因为l永远不可能大于等于r
* 3,l+r+1要取中间值,
*/
public void mergeSort(Integer[] a,int l,int r){
// 这里注意,只能用成减法
if (r - l <= 1){
return;
}
// 这里要取奇数的中间值
int mid = (l+r+1)/2;
mergeSort(a,l,mid);
mergeSort(a,mid,r);
merge(a,l,mid,r);
}
// 合并两个数组
/**
* 合并的原理:
* 1,将两个数组复制到另外两个数组,然后将两个数组合并到一个数组。
*
*/
private void merge(Integer[] a, int l, int mid, int r) {
// Integer[] lef = Arrays.copyOfRange(a, l, mid+1);
// Integer[] rig = Arrays.copyOfRange(a, mid, r+1);
Integer[] lef = Arrays.copyOfRange(a, l, mid);
Integer[] rig = Arrays.copyOfRange(a, mid, r);
int ri = 0;
int le = 0;
// lef[lef.length -1] = rig[rig.length-1] = Integer.MAX_VALUE;
// for (int i = l; i < r; i++){
// if (lef[le] < rig[ri]){
// a[i] = lef[le++];
// }else{
// a[i] = rig[ri++];
// }
// }
for (int i = l; i < r; i++){
if (le < lef.length && ri < rig.length && lef[le] < rig[ri]){
a[i] = lef[le++];
}else if (le >= lef.length && ri < rig.length){
a[i] = rig[ri++];
}else if (ri >= rig.length && le < lef.length ){
a[i] = lef[le++];
}else if (le < lef.length && ri < rig.length){
a[i] = rig[ri++];
}
}
}
}