调Bug:
1通读程序
2输出中间值
3减功能(定位)
归并排序(merge sort)
先分为两部分,对第一部分看是否排好了,没有则再分为两部分,不断细分,直到得到两个已经排好序的数组。然后再新开辟一个和原数组等长的空间,设置三个变量,ijk,依次比较后,放在新空间里,注意要判断两部分是否都走完了(因为可能第一部分全放进去了,第二部分还没放进去)
时间复杂度为 O(N*logN),因为1⃣️二分,logN次,2⃣️每次遍历N。
额外空间复杂度O(N),因为最多只需要生成一个长度为N的辅助空间用来存help。
归并排序比冒泡、插入排序比较快的原因,是因为小组合成大组的过程中,小组内本身排好的顺序被利用了起来。
/**
* @author mino
* @date 2022/2/25 8:44 下午
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {1,6,0,2,3,4,8};//奇数比较好验证
sort(arr,0,arr.length-1);
print(arr);
}
static void sort(int[] arr,int left,int right){//递归在这里
if(left == right) return;//递归的basecase!!
//分成两边
int mid = left + (right - left)/2;//l+r-l 防止角标越界
//排左边
sort(arr,left,mid);
//排右边
sort(arr,mid+1,right);
merge(arr,left,mid+1,right);
}
static void merge(int[] arr,int leftP,int rightP,int rightB){//两部分已经排好序了,进行并归
//左部分第一个位置;右部分第一个位置;末尾位置
int[] temp = new int[rightB - leftP + 1];
int i = leftP;//左边第一个
int j = rightP;//右边第一个
int k = 0;//temp的第一个
while(i < rightP && j <= rightB){//末尾位置要包含在内
// if(arr[i]<=arr[j] ){//小于等于 :保证稳定性
// temp[k++] = arr[i++];
// }else {
// temp[k++] = arr[j++];
// }
temp[k++] = arr[i]<=arr[j] ? arr[i++] : arr[j++];//简化语句
}
while(i<rightP) temp[k++] = arr[i++];//检查有没有剩下的。
while(j<=rightB) temp[k++] = arr[j++];
print(temp);
System.out.println();
for(int n = 0;n<temp.length;n++){//temp替换arr
arr[leftP+n] = temp[n];
}
}
static void print(int[] arr){
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]+" ");
}
}
static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
快速排序
快速排序的核心思想是按基准值分区
计数排序:适合量大但是范围小
某大型企业数万名员工年龄排序
如何快速得知高考名次(腾讯面试)
空间复杂度n+k(数组长度和计数长度count)
N*2 --> N>>1 左移
N*2 +1–> ((N>>1) | 1) 左移再或一个1