一、快速排序
1.快排思想
(1) 确定分界点,把数组分成两部分。
常用的分界点有:数组第一个数,数组最后一个数,数组中间那个数
一般我会选用数组中间那个数作为分界点,这样后面的写法也固定了,不容易遇到边界问题。
(2) 根据分界点调整数组,使得分界点左边的数都小于等于分界点,分界点右边的数都大于等于分界点
方法:利用双指针的移动,左指针在左边大于分界点的数停下,右指针在右边小于分界点的数停下,交换这两个数。
(3) 递归处理左右两边。
(4) 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)。
2.快排模板
public static void quickSort(int[] arr,int l ,int r){
if(l >= r) return; //递归结束条件
int i = l - 1; //左指针
int j = r + 1; //右指针
int x = arr[l + ((r - l) >> 1)]; //选取数组中间的那个数作为分界点,把数组分成两部分
while(i < j){
do{
i++;
}while(arr[i] < x); //在左边大于分界点的数停下
do{
j--;
}while(arr[j] > x); //在右边小于分界点的数停下
if(i < j){ //交换两个数
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
quickSort(arr,l,j); //递归处理左边
quickSort(arr,j+1,r); //递归处理右边
}
二、归并排序
1.归并排序思想
(1) 将数组平均分成两部分(奇数个数的话就是一部分为 n / 2 n/2 n/2个元素,另一部分为 n / 2 + 1 n/2+1 n/2+1个元素)。
(2) 分别递归地排序数组的这两部分。
(3) 将排好序的两部分归并成一整块。
方法:利用双指针的移动,将两部分中更小的那个数存到临时存储数组中。
(4) 时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。
2.归并排序模板
public static void mergeSort(int[] arr,int l,int r){
if(l >= r) return; //递归结束条件
int mid = l + (r - l)/2; //将数组分成[l,mid] 和 [mid+1,R] 两部分
mergeSort(arr,l,mid); //递归排序左半部分
mergeSort(arr,mid+1,r); //递归排序右半部分
int i = l; //左半部分的指针
int j = mid + 1; //右半部分的指针
int k = 0; //临时存储数组的索引
while(i <= mid && j <= r){ //循环找到两部分中更小的那个数
if(arr[i] <= arr[j]) temp[k++] = arr[i++];
else temp[k++] = arr[j++]; //temp为临时存储数组
}
while(i <= mid) temp[k++] = arr[i++]; //把左半部分没存入的数存到临时存储数组中
while(j <= r) temp[k++] = arr[j++]; //把右半部分没存入的数存到临时存储数组中
for(i = l,j = 0; i <= r; i++,j++){ //将临时存储数组中排好序的数复制到原数组中
arr[i] = temp[j];
}
}
更多文章欢迎关注我的公众号ACJavaBear,一起学Java吧~