选择排序
public static void selectSort(int[] arr){
//边界判断啊
if(arr == null || arr.length < 2 ){
return ;
}
int minIndex;
//外循环是对1-n 取最小值,2-n 取最小值
for(int i = 0; i < arr.length-1; i++){
minIndex = i;
for(int j = i+1; j<arr.length -1 ; j++){
//判断
minIndex = arr[j] < arr[minIndex]? j : minIndex;
}
//交换
swap(arr, i, minIndex);
}
}
//交换位置
public static void swap(int[] arr,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
冒泡排序
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// 0 ~ N-1
// 0 ~ N-2
// 0 ~ N-3
//冒泡排序是优先将最大值先排好
for (int e = arr.length - 1; e > 0; e--) { // 0 ~ e
for (int i = 0; i < e; i++) {
//大的值往后放
if (arr[i] > arr[i + 1]) {
swap(arr, i, i + 1);
}
}
}
}
// 交换arr的i和j位置上的值
// 这种等同于tmp做中间变量的交换
public static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
插入排序
public static void insertionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// 不只1个数
for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序
//当j--后 j为-1时,代表这个小排序达成,跳出,进行接下来的排序
for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
swap(arr, j, j + 1);
}
}
}
// i和j是一个位置的话,会出错
public static void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
归并排序
递归方法
public static void process(int[] arr, int L, int R) {
if (L == R) { // 如果左边界 = 右边界,那其实不用排序
return;
}
// 这是求的中点
int mid = L + ((R - L) >> 1);
// 递归左 --- 中点
process(arr, L, mid);
// 递归中点 --- 右
process(arr, mid + 1, R);
//merge是让他们拼凑在一起
merge(arr, L, mid, R);
}
public static void merge(int[] arr, int L, int M, int R) {
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = M + 1;
// 这里p1和p2是要都不越界才可以继续进行
while (p1 <= M && p2 <= R) {
//p1和p2谁指到的数大,谁就把他放在help这个新数组里,++是因为如果放到了新数组,我需要指针往下移
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
// 如果跳出来while循环,要么p1越界了,要么p2越界了
// 那么无论是p1还是p2越界了,对方一定是排好序的最大值,直接放到新数组就好
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
}
非递归
public static void mergeSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
// 步长
int mergeSize = 1;
// 当步长 > N的时候 就可以跳出while了
while (mergeSize < N) { // log N
// 当前左组的,第一个位置
int L = 0;
while (L < N) {
if (mergeSize >= N - L) {
break;
}
int M = L + mergeSize - 1;
int R = M + Math.min(mergeSize, N - M - 1);
merge(arr, L, M, R);
L = R + 1;
}
// 防止溢出
if (mergeSize > N / 2) {
break;
}
//其实就是步长 x 2
mergeSize <<= 1;
}
}
归并排序
递归方法
public static void process(int[] arr, int L, int R) {
if (L == R) { // 如果左边界 = 右边界,那其实不用排序
return;
}
// 这是求的中点
int mid = L + ((R - L) >> 1);
// 递归左 --- 中点
process(arr, L, mid);
// 递归中点 --- 右
process(arr, mid + 1, R);
//merge是让他们拼凑在一起
merge(arr, L, mid, R);
}
public static void merge(int[] arr, int L, int M, int R) {
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = M + 1;
// 这里p1和p2是要都不越界才可以继续进行
while (p1 <= M && p2 <= R) {
//p1和p2谁指到的数大,谁就把他放在help这个新数组里,++是因为如果放到了新数组,我需要指针往下移
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
// 如果跳出来while循环,要么p1越界了,要么p2越界了
// 那么无论是p1还是p2越界了,对方一定是排好序的最大值,直接放到新数组就好
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
}
非递归
public static void mergeSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
// 步长
int mergeSize = 1;
// 当步长 > N的时候 就可以跳出while了
while (mergeSize < N) { // log N
// 当前左组的,第一个位置
int L = 0;
while (L < N) {
if (mergeSize >= N - L) {
break;
}
int M = L + mergeSize - 1;
int R = M + Math.min(mergeSize, N - M - 1);
merge(arr, L, M, R);
L = R + 1;
}
// 防止溢出
if (mergeSize > N / 2) {
break;
}
//其实就是步长 x 2
mergeSize <<= 1;
}
}