在计算机科学中,排序是一项基本且重要的操作。排序算法的效率直接影响到数据处理的性能和速度。在Java中,我们可以使用不同的排序算法来处理数据,下面将介绍七种常见的排序算法,并给出Java代码示例及其特点。
1. 直接插入排序
直接插入排序是一种简单的排序算法,通过构建一个有序序列,对未排序的数据逐个插入到已排序的序列中。
public void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
2. 希尔排序
希尔排序是对插入排序的一种改进,其通过对间隔序列进行插入排序,使得整体数据趋向于有序,从而减少后续的排序次数。
public void shellSort(int[] arr) {
int n = arr.length;
for (int gap = n / 2; gap > 0; gap /= 2) {
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;
}
}
}
3. 归并排序
归并排序是一种分治法排序算法,将数组分为两半,分别排序后再合并。其时间复杂度为O(n log n)。
public void mergeSort(int[] arr) {
if (arr.length < 2) return;
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);
}
private 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++];
}
4. 选择排序
选择排序的基本思路是每次从未排序的部分选择最小元素,放到已排序部分的后面。
public void selectionSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
5. 堆排序
堆排序利用堆这种数据结构,通过构建最大堆和不断地取出最大值,最终实现排序。
public void heapSort(int[] arr) {
int n = arr.length;
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
for (int i = n - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
private void heapify(int[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
heapify(arr, n, largest);
}
}
6. 冒泡排序
冒泡排序是通过重复交换相邻的逆序元素,把大的元素“冒泡”到数组的最后。
public void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
7. 快速排序
快速排序是通过选择一个“基准”元素,将数组分为两个部分,对这两部分递归地进行相同的操作,直到整个数组有序。
public void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
private 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++;
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;
}
计数排序(非比较排序)
计数排序是一种非比较排序算法,适用于范围较小的整数排序。它通过计数元素频率,依次填充排序结果。
public void countingSort(int[] arr) {
int max = Arrays.stream(arr).max().getAsInt();
int[] count = new int[max + 1];
for (int num : arr) {
count[num]++;
}
int index = 0;
for (int i = 0; i < count.length; i++) {
while (count[i] > 0) {
arr[index++] = i;
count[i]--;
}
}
}
以上就是七种排序算法的 Java 实现及其特点简介。不同的排序算法适用于不同的数据集和需求,选择合适的排序算法可以显著提高程序的性能。希望通过这些示例,能够帮助读者更好地理解和应用排序算法。