《Java 排序算法新视界:八大排序算法全解析》
《Java 排序算法新视界:八大排序算法全解析》
一、八大排序算法
1. 冒泡排序(Bubble Sort)
原理
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
代码示例
public class BubbleSort {
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]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( 1 ) O(1) O(1)
2. 选择排序(Selection Sort)
原理
选择排序每次从未排序部分选出最小元素,放到已排序部分的末尾。
代码示例
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;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( 1 ) O(1) O(1)
3. 插入排序(Insertion Sort)
原理
插入排序通过构建有序序列,对未排序数据在已排序序列中从后向前扫描,找到相应位置插入。
代码示例
public class InsertionSort {
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;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
}
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( 1 ) O(1) O(1)
4. 希尔排序(Shell Sort)
原理
希尔排序按增量分组进行插入排序,逐渐减少增量直至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;
}
}
}
}
复杂度分析
- 时间复杂度:约 O ( n 1.3 ) O(n^{1.3}) O(n1.3)
- 空间复杂度: O ( 1 ) O(1) O(1)
5. 归并排序(Merge Sort)
原理
归并排序采用分治法,将数组分成两半递归排序,再合并有序数组。
代码示例
public class MergeSort {
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = (left + right)/2;
mergeSort(arr, left, mid);
mergeSort(arr, mid+1, right);
merge(arr, left, mid, right);
}
}
}
复杂度分析
- 时间复杂度: O ( n log n ) O(n \log n) O(nlogn)
- 空间复杂度: O ( n ) O(n) O(n)
6. 快速排序(Quick Sort)
原理
快速排序选择基准元素,将数组分为小于基准和大于基准的两部分,递归排序。
代码示例
public class QuickSort {
public static 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);
}
}
}
复杂度分析
- 时间复杂度:平均 O ( n log n ) O(n \log n) O(nlogn),最坏 O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( log n ) O(\log n) O(logn)
7. 堆排序(Heap Sort)
原理
堆排序构建最大堆,将堆顶元素与末尾交换,调整剩余元素为最大堆。
代码示例
public class HeapSort {
public static 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);
}
}
}
复杂度分析
- 时间复杂度: O ( n log n ) O(n \log n) O(nlogn)
- 空间复杂度: O ( 1 ) O(1) O(1)
8. 计数排序(Counting Sort)
原理
计数排序统计元素出现次数,按计数重建有序数组。
代码示例
public class CountingSort {
public static void countingSort(int[] arr) {
int max = Arrays.stream(arr).max().getAsInt();
int min = Arrays.stream(arr).min().getAsInt();
int[] count = new int[max-min+1];
for (int num : arr) count[num-min]++;
int index =0;
for (int i=0; i<count.length; i++) {
while (count[i]>0) {
arr[index++] = i+min;
count[i]--;
}
}
}
}
复杂度分析
- 时间复杂度: O ( n + k ) O(n+k) O(n+k)
- 空间复杂度: O ( k ) O(k) O(k)