Java 中的六大排序算法包括:冒泡排序(Bubble Sort)、选择排序(Selection Sort)、插入排序(Insertion Sort)、希尔排序(Shell Sort)、归并排序(Merge Sort)和快速排序(Quick Sort)。下面是对这些排序算法的详细介绍以及相应的 Java 代码实现。
- 冒泡排序(Bubble Sort)
冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
java
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交换 arr[j] 和 arr[j+1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
- 选择排序(Selection Sort)
选择排序是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
java
public static void selectionSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// 交换找到的最小元素和第 i 个元素
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
- 插入排序(Insertion Sort)
插入排序的工作方式是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
java
public static void insertionSort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; ++i) {
int key = arr[i];
int j = i - 1;
/* 将大于 key 的元素后移 */
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
- 希尔排序(Shell Sort)
希尔排序是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法的基本思想是:先将整个待排序的记录序列分割成为若干子序列(由相隔某个"增量"的记录组成)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的记录"基本有序"时,再对全体记录进行一次直接插入排序。
java
public static void shellSort(int[] arr) {
int n = arr.length;
int gap = n / 2;
while (gap > 0) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
gap /= 2;
}
}
- 归并排序(Merge Sort)
归并排序是一种分治策略的排序算法。它将一个大数组分割成两个小数组,分别对这两个小数组进行排序,然后将排序好的小数组合并成一个有序的大数组。
java
public static void mergeSort(int[] arr) {
if (arr.length < 2) {
return; // 数组长度小于2时,不需要排序
}
int mid = arr.length / 2;
int[] left = Arrays.copyOfRange(arr, 0, mid);
int[] right = Arrays.copyOfRange(arr, mid, arr.length);
mergeSort(left); // 对左半部分进行排序
mergeSort(right); // 对右半部分进行排序
merge(arr, left, right); // 合并两个有序数组
}
public static void merge(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, k = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
arr[k++] = left[i++];
} else {
arr[k++] = right[j++];
}
}
while (i < left.length) {
arr[k++] = left[i++];
}
while (j < right.length) {
arr[k++] = right[j++];
}
}
- 快速排序(Quick Sort)
快速排序是一种高效的排序算法,它使用分治法的策略来把一个数组排序。快速排序的基本思想是:通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
java
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1); // 对左半部分进行递归排序
quickSort(arr, pivotIndex + 1, high); // 对右半部分进行递归排序
}
}
public static int partition(int[] arr, int low, int high) {
int pivot = arr[high]; // 选择最右边的元素作为枢轴
int i = low - 1; // 指向最小元素的指针
for (int j = low; j < high; j++) {
// 如果当前元素小于或等于枢轴
if (arr[j] <= pivot) {
i++; // 增加最小元素指针
// 交换 arr[i] 和 arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 将枢轴放到正确的位置
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
使用这些排序算法时,请注意它们的时间复杂度和空间复杂度,以及它们的稳定性。在实际应用中,选择合适的排序算法取决于数据的规模、分布以及排序的要求。对于小规模的数组,简单的排序算法(如冒泡排序、插入排序)可能就足够了。对于大规模的数组,通常选择更高效的排序算法(如归并排序、快速排序)。