一、快速排序思想:
1.确定分界点,把数组分成两部分。
常用的分界点有 数组第一个数,数组最后一个数,数组中间那个数
一般我会选用数组中间那个数作为分界点,这样后面的写法也固定了,不容易遇到边界问题。
2.根据分界点调整数组,使得分界点左边的数都小于等于分界点,分界点右边的数都大于等于分界点
方法:利用双指针的移动,左指针在左边大于分界点的数停下,右指针在右边小于分界点的数停下,交换这两个数。
3.分别递归处理左右两边。
4.时间复杂度为O(nlogn)。
快排Java代码模板
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.将数组平均分成两部分(奇数个数的话就是一个为n/2个,一个为n/2+1个)。
2.分别递归地排序数组的这两部分。
3.将排好序的两部分归并成一整块。
方法:利用双指针的移动,将两部分中更小的那个数存到临时存储数组中。
4.时间复杂度为O(nlogn)。
归并Java代码模板
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];
}
}
在快排思想中,第2部分中的方法,左指针在左边大于等于分界点的地方停下来,右指针在右边小于等于分界点的地方停下来,然后交换,你在上面和代码备注中少了等于,这是避免处理越界问题的关键。