重点是体会思想,分治与递归
package 高级排序;
import static 排序算法.Main.swap;
/**
* 先研究一下快速排序,归并排序、计数排序(桶排序)
*
* */
public class Main {
/**
* 归并排序:先拆后合,用上了递归的思想,再加两个数组合成一个有序数组
* */
public static void guibing(int[] arr){
int len = arr.length;
//有排序的范围:[0,len-1]
mergsort(arr,0,len -1);
}
private static void mergsort(int[] arr, int start, int end) {
//递归到数组元素为一个时截止,就开始从下往上排序。
if (start < end) {
int mid = (start+end)/2;
mergsort(arr,start,mid);
mergsort(arr,mid+1,end);
mergepaihaoxu(arr, start, mid, mid + 1, end);
}
}
private static void mergepaihaoxu(int[] arr, int start1, int end1, int start2, int end2) {
int i = start1;
int j = start2;
int[] temArray = new int[end2 - start1 + 1];
int k = 0;
//遍历两个数组、比价大小、放到新数组中
while (i<=end1&&j<=end2){
if(arr[i]<arr[j]){
temArray[k] = arr[i];
k++;
i++;
}else{
temArray[k] =arr[j];
j++;
k++;
}
}
//存在一个数组遍历完了,另一个数组元素直接放入
while (i<=end1){
temArray[k++] = arr[i++];
}
while (j<=end2){
temArray[k++] = arr[j++];
}
//新数组回填老数组,从start1开始。
for(int m = 0; m < temArray.length;m++){
arr[m+start1] = temArray[m];
}
}
/**
* 快速排序:
* 用到了分治的思想,对partition左右两边,再接着排序
* 选取基准数(一般数组第一个), 以基准数为参考,移动原来元素,保证左边小于基准数,右边大于基准数,返回基准数下标。
* */
public static void kaisu(int[] arr){
int len = arr.length;
int low = 0;
int high = len -1;
qsort(arr, low, high);
}
private static void qsort(int[] arr, int low, int high) {
int pos;
if (low < high) {
//先找到分治点的下标,对两边分治一下
pos = partition(arr, low, high);
qsort(arr,low,pos-1);
qsort(arr,pos+1,high);
}
}
//找分治点的实现
private static int partition(int[] arr, int low, int high) {
//选取第一个元素作为基准,注意不是arr[0]
int key = arr[low];
while (low < high) {
while (arr[high]>=key&&high>low)
high--;
swap(arr, low, high);
//发生交换后,从low下标开始比较
while (arr[low]<=key&low<high)
low ++;
swap(arr,low,high);
}
return high;
}
/**
* 桶排序的思想,适用于范围小的数字排序
* */
public static void main(String[] args) {
int[] array = {1,3,5,7,2,4,9,8};
kaisu(array);
for (int i : array){
System.out.print(i+" ");
}
}
}