java常用排序算法
java常用排序算法
冒泡排序
public static void bubble(int[] arr) {
int tem;
for (int i = 1; i < arr.length; ++i) {
// 负辅助变量,用于提前结束
int count = 0;
for (int j = 1; j < arr.length; ++j) {
if (arr[j - 1] > arr[j]) {
tem = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tem;
// 减少赋值判断
if (count == 0) {
++count;
}
}
}
if (count == 0) {
break;
}
}
}
选择排序
public static void select(int[] arr) {
for (int i = 0; i < arr.length - 1; ++i) {
// 找到最小值和下标
int minIndex = i;
int min = arr[i];
for (int j = i + 1; j < arr.length; ++j) {
if (min > arr[j]) {
min = arr[j];
minIndex = j;
}
}
// 交换
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
插入排序
public static void insert(int[] arr) {
for (int i = 1; i < arr.length; ++i) {
int insertValue = arr[i];
int insertIndex = i - 1;
while (insertIndex >= 0 && insertValue < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
--insertIndex;
}
arr[insertIndex + 1] = insertValue;
}
}
希尔排序
交换法
public static void shell01(int[] arr) {
int temp;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; ++i) {
for (int j = i - gap; j >= 0; j -= gap) {
if (arr[j] > arr[j + gap]) {
temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
}
}
位移法
public static void shell02(int[] arr) {
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; ++i) {
// 保存下标和值
int index = i;
int temp = arr[index];
while (index - gap >= 0 && temp < arr[index - gap]) {
// 移动
arr[index] = arr[index - gap];
index -= gap;
}
arr[index] = temp;
}
}
}
快速排序
public static void quick(int[] arr, int left, int right) {
int l = left;
int r = right;
int mid = left + (right - left) / 2;
int pivot = arr[mid];
int temp = 0;
// 结束条件为
// 左下标在右下标右边就进不去了
while (l < r) {
// 找到左右需要交换的数
while (arr[l] < pivot) {
// 找不到移动下标
++l;
}
while (arr[r] > pivot) {
--r;
}
// 找到后交换
if (l >= r) {
// 没找到
break;
}
// 交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
// 如果交换完后发现左右值和中值相等的情况
if (arr[l] == pivot) {
--r;
}
if (arr[r] == pivot) {
++l;
}
}
// 如果l == r,必须l右移,r左移
if (l == r) {
++l;
--r;
}
// 左递归
if (left < r) {
quick(arr, left, r);
}
// 右递归
if (right > l) {
quick(arr, l, right);
}
}
归并排序
/**
* 分+合
*/
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
// 分
int mid = left + (right - left) / 2;
// 向左递归分解
mergeSort(arr, left, mid, temp);
// 向右递归
mergeSort(arr, mid + 1, right, temp);
// 分解完合并
merge(arr, left, mid, right, temp);
}
}
/**
* 合并
*
* @param arr 排序的原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
// 左边有序序列的初始索引
int i = left;
// 右边有序序列的初始索引
int j = mid + 1;
// temp数组的索引
int t = 0;
// 左右两边初始数组按规则拷贝到temp
// 直到有一边的有序数组处理完毕
while (i <= mid && j <= right) {
// 判断
if (arr[i] > arr[j]) {
temp[t++] = arr[j++];
} else if (arr[j] > arr[i]) {
temp[t++] = arr[i++];
} else {
temp[t++] = arr[i++];
temp[t++] = arr[j++];
}
}
// 把有剩下数组的数据依次填充到temp
while (i <= mid) {
temp[t++] = arr[i++];
}
while (j <= right) {
temp[t++] = arr[j++];
}
// 将temp数组copy到arr中
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft++] = temp[t++];
}
}
基数排序
public static void radix(int[] arr) {
// 桶
int[][] bucket = new int[10][arr.length];
// 桶下标
int[] bucketIndex = new int[10];
// 找到最大值
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
max = arr[i] > max ? arr[i] : max;
}
// 得到最大值位数
int maxLenth = (max + "").length();
for (int i = 0, n = 1; i < maxLenth; ++i, n *= 10) {
// 按规则放入桶
for (int j = 0; j < arr.length; j++) {
int element = (arr[j] / n) % 10;
bucket[element][bucketIndex[element]++] = arr[j];
}
// 从桶里放到arr
int index = 0;
for (int k = 0; k < bucketIndex.length; k++) {
// 如果桶里没数据就不管他
if (bucketIndex[k] != 0) {
// 循环放入
for (int l = 0; l < bucketIndex[k]; l++) {
arr[index++] = bucket[k][l];
}
}
bucketIndex[k] = 0;
}
}
}
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步