Java数组排序(其二)(常见排序算法)

发布于:2024-12-21 ⋅ 阅读:(160) ⋅ 点赞:(0)

在Java中,对数组进行排序是非常常见的需求。Java提供了多种内置方法来简化这一过程,同时也允许开发者根据具体需求实现自定义的排序逻辑。以下是几种常用的Java数组排序方法:

内置排序方法

使用Arrays.sort()

这是最直接也是最常用的方法之一。java.util.Arrays类提供了一个静态方法sort(),它可以对基本数据类型(如intdouble等)以及实现了Comparable接口的对象数组进行升序排序。对于对象数组,默认情况下是按照自然顺序排序,即对象必须实现Comparable接口,并且定义了比较规则。

升序排序:只需要调用Arrays.sort(array)即可完成从小到大的排序。

降序排序:可以通过传递一个Comparator对象给Arrays.sort()来改变排序顺序。例如,使用Collections.reverseOrder()作为参数可以实现从大到小的排序。

import java.util.Arrays;
import java.util.Collections;

public class SortExample {
    public static void main(String[] args) {
        Integer[] numbers = {5, 3, 9, 1, 4};
        Arrays.sort(numbers, Collections.reverseOrder());
        System.out.println(Arrays.toString(numbers));
    }
}
使用Collections.sort()

当处理的是实现了List接口的数据结构时,比如ArrayList,可以使用java.util.Collections提供的sort()方法。这个方法同样支持通过传递Comparator来自定义排序规则。需要注意的是,Collections.sort()只能用于列表类型的集合,不能直接应用于普通数组。

自定义排序算法

除了利用内置的方法外,还可以自己编写排序算法。虽然这通常不是必需的,但在某些特殊情况下可能会更加灵活或性能更优。常见的手工实现的排序算法包括但不限于:

冒泡排序:通过重复地遍历要排序的列表,依次比较相邻元素并交换它们的位置,直到整个列表变得有序为止。尽管简单易懂,但其时间复杂度为O(n^2),效率较低。

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // Swap arr[j] and arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            // If no two elements were swapped by inner loop, then break
            if (!swapped)
                break;
        }
    }

    public static void main(String[] args) {
        int[] array = {64, 34, 25, 12, 22, 11, 90};
        System.out.println("Unsorted array: " + Arrays.toString(array));
        bubbleSort(array);
        System.out.println("Sorted array: " + Arrays.toString(array));
    }
}

选择排序:每次从未排序部分选出最小(或最大)的一个元素,将其放到已排序序列的末尾。它的时间复杂度同样是O(n^2),但在特定条件下可能比冒泡排序更快。

public class SelectionSort {
    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;
                }
            }
            // Swap arr[i] and arr[minIndex]
            int temp = arr[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp;
        }
    }

    public static void main(String[] args) {
        int[] array = {64, 25, 12, 22, 11};
        System.out.println("Unsorted array: " + Arrays.toString(array));
        selectionSort(array);
        System.out.println("Sorted array: " + Arrays.toString(array));
    }
}

插入排序:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。适用于小规模数据集。

public class InsertionSort {
    public static void insertionSort(int[] arr) {
        for (int i = 1; i < arr.length; ++i) {
            int key = arr[i];
            int j = i - 1;

            /* Move elements of arr[0..i-1], that are greater than key,
               to one position ahead of their current position */
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j = j - 1;
            }
            arr[j + 1] = key;
        }
    }

    public static void main(String[] args) {
        int[] array = {12, 11, 13, 5, 6};
        System.out.println("Unsorted array: " + Arrays.toString(array));
        insertionSort(array);
        System.out.println("Sorted array: " + Arrays.toString(array));
    }
}

快速排序:采用分治法策略,将原问题分解成若干个规模较小的问题,然后递归求解子问题。它是实践中非常高效的排序算法之一,平均时间复杂度为O(n log n)。Arrays.sort()内部对于基本数据类型实际上就是基于优化后的快速排序实现。

public class QuickSort {
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            // pi is partitioning index, arr[pi] is now at right place
            int pi = partition(arr, low, high);

            // Recursively sort elements before partition and after partition
            quickSort(arr, low, pi - 1);
            quickSort(arr, pi + 1, high);
        }
    }

    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = (low - 1); // Index of smaller element

        for (int j = low; j < high; j++) {
            // If current element is smaller than or equal to pivot
            if (arr[j] <= pivot) {
                i++;

                // Swap arr[i] and arr[j]
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        // Swap arr[i+1] and arr[high] (or pivot)
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;

        return i + 1;
    }

    public static void main(String[] args) {
        int[] array = {10, 7, 8, 9, 1, 5};
        int n = array.length;
        System.out.println("Unsorted array: " + Arrays.toString(array));
        quickSort(array, 0, n - 1);
        System.out.println("Sorted array: " + Arrays.toString(array));
    }
}

其他排序方式

  • Shell排序:希尔排序是一种改进版的插入排序,它通过比较相隔一定间隔的元素来进行排序,随着排序的进行逐渐减少间隔直至变为1。这种方法可以在一定程度上提高插入排序的效率。

public class ShellSort {
    public static 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;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = {23, 12, 1, 8, 34, 54, 2, 3};
        System.out.println("Unsorted array: " + Arrays.toString(array));
        shellSort(array);
        System.out.println("Sorted array: " + Arrays.toString(array));
    }
}
  • 归并排序:该算法也是基于分治思想,但是与快速排序不同的是,它总是将数组分成两半,分别对左右两边排序后再合并结果。Arrays.sort()对于对象数组会使用归并排序以保证稳定性。

    分别有这个实例

    递归排序:快速排序

public class QuickSort {
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            // pi is partitioning index, arr[pi] is now at right place
            int pi = partition(arr, low, high);

            // Recursively sort elements before partition and after partition
            quickSort(arr, low, pi - 1);
            quickSort(arr, pi + 1, high);
        }
    }

    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[high];
        int i = (low - 1); // Index of smaller element

        for (int j = low; j < high; j++) {
            // If current element is smaller than or equal to pivot
            if (arr[j] <= pivot) {
                i++;

                // Swap arr[i] and arr[j]
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }

        // Swap arr[i+1] and arr[high] (or pivot)
        int temp = arr[i + 1];
        arr[i + 1] = arr[high];
        arr[high] = temp;

        return i + 1;
    }

    public static void main(String[] args) {
        int[] array = {10, 7, 8, 9, 1, 5};
        System.out.println("Unsorted array: " + Arrays.toString(array));
        quickSort(array, 0, array.length - 1);
        System.out.println("Sorted array: " + Arrays.toString(array));
    }
}

数学计算:斐波那契数列

public class Fibonacci {
    public static int getFibonacci(int number) {
        if (number <= 1) {
            return number;
        }
        return getFibonacci(number - 1) + getFibonacci(number - 2);
    }

    public static void main(String[] args) {
        int n = 10; // Example input
        System.out.println("Fibonacci number at position " + n + ": " + getFibonacci(n));
    }
}

这位博主有动态效果图有兴趣可以进往观看:https://juejin.cn/post/694175771133211444