快速排序
算法采用了分治的思想
java
public static void main(String[] args) {
int[] arr = new int[]{45, 2, 42, 89, 0, 311, 299, 20};
fastSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
public static void fastSort(int[] arr, int left, int right) {
// 不用left==right,是因为这样会造成空指针
if (left >= right) {
return;
}
int i = left;// i从0开始
int j = right;
// 基准数字
int num = arr[left];
// 只要i和j还没有相遇,就要一直交换
while (i != j) {
// 右指针j向左移动去找比基准数字大的第一个数字,找的过程中保证i,j不相遇
while (arr[j] >= num && i != j) {
j--;
}
// 左指针i向右移动去找比基准数字小的第一个数字,找的过程中保证i,j不相遇
while (arr[i] <= num && i != j) {
i++;
}
// 交换i和j指向的数字
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// i,j相遇之后,交换基准数字和ij相遇位置的数字
int temp = arr[left];
arr[left] = arr[i];
arr[i] = temp;
// 上面的操作完成之后,就能保证基准数字在中位数的位置上,同时保证基准数字左边的数字都比它小,右边的数字都比它大
// 排序基准数字左半边
fastSort(arr, left, i - 1);
// 排序基准数字右半边
fastSort(arr, i + 1, right);
}
归并排序
arr先保证局部有序,再慢慢变得整体有序
实际并没有分割数组
java
public static void mergeSort(int[] arr, int left, int right, int mid) {
// 归并排序的过程是先分组,然后两两合并,最终变得有序
// 左指针不小于右指针时,递归结束
if (left >= right) {
return;
}
// 先分组左半部分,本质是将指针指向
mergeSort(arr, left, mid, (left + mid) / 2);
// 再分组右半部分
mergeSort(arr, mid + 1, right, (mid + 1 + right) / 2);
// 分好组之后,合并排序
sort(arr, left, right, mid);
}
public static void sort(int[] arr, int left, int right, int mid) {
// 临时数组保存排序数据
int[] temp = new int[right - left + 1];
int s1 = left;
int s2 = mid + 1;
// 比较两个序列之间的最小数谁最小,放入temp中
int i = 0;
while (s1 <= mid && s2 <= right) {
if (arr[s1] < arr[s2]) {
temp[i] = arr[s1];
i++;
s1++;
} else {
temp[i] = arr[s2];
i++;
s2++;
}
}
// 将剩余数字放入temp中
while (s1 <= mid) {
temp[i] = arr[s1];
i++;
s1++;
}
while (s2 <= right) {
temp[i] = arr[s2];
i++;
s2++;
}
// 数据从临时数组取出,覆盖原数组
for (int j = 0; j < temp.length; j++) {
// 注意是left + j,因为temp是小数组
arr[left + j] = temp[j];
}
}