• 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]) {
                        // Swap arr[j] and arr[j+1]
                        int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    优缺点:
    • 优点:
      • 实现简单,代码短小。
    • 缺点:
      • 效率较低,时间复杂度为O(n^2)。

    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 minIdx = i;
                for (int j = i + 1; j < n; j++) {
                    if (arr[j] < arr[minIdx])
                        minIdx = j;
                }
                int temp = arr[minIdx];
                arr[minIdx] = arr[i];
                arr[i] = temp;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    优缺点:
    • 优点:
      • 实现简单,不占用额外空间。
    • 缺点:
      • 效率较低,时间复杂度为O(n^2)。

    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 = j - 1;
                }
                arr[j + 1] = key;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    优缺点:
    • 优点:
      • 实现简单,对小规模数据或接近有序的数据排序效率高。
    • 缺点:
      • 效率较低,时间复杂度为O(n^2)。

    4. 归并排序 (Merge Sort)

    解题思路:
    • 将数组递归分成子数组,然后合并这些子数组,合并过程中保持有序。
    实现代码:
    public class MergeSort {
        public static void merge(int[] arr, int left, int middle, int right) {
            int n1 = middle - left + 1;
            int n2 = right - middle;
    
            int[] L = new int[n1];
            int[] R = new int[n2];
    
            for (int i = 0; i < n1; i++)
                L[i] = arr[left + i];
            for (int j = 0; j < n2; j++)
                R[j] = arr[middle + 1 + j];
    
            int i = 0, j = 0, k = left;
    
            while (i < n1 && j < n2) {
                if (L[i] <= R[j]) {
                    arr[k] = L[i];
                    i++;
                } else {
                    arr[k] = R[j];
                    j++;
                }
                k++;
            }
    
            while (i < n1) {
                arr[k] = L[i];
                i++;
                k++;
            }
    
            while (j < n2) {
                arr[k] = R[j];
                j++;
                k++;
            }
        }
    
        public static void mergeSort(int[] arr, int left, int right) {
            if (left < right) {
                int middle = left + (right - left) / 2;
    
                mergeSort(arr, left, middle);
                mergeSort(arr, middle + 1, right);
    
                merge(arr, left, middle, right);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    优缺点:
    • 优点:
      • 稳定,时间复杂度为O(n log n)。
    • 缺点:
      • 需要额外的内存空间。

    5. 快速排序 (Quick Sort)

    解题思路:
    • 选择一个基准元素,将数组分为小于基准和大于基准的两部分,然后递归地对这两部分进行排序。
    实现代码:
    public class QuickSort {
        public static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
        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++;
                    swap(arr, i, j);
                }
            }
            swap(arr, i + 1, high);
            return i + 1;
        }
    
        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);
    
    
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    优缺点:
    • 优点:
      • 效率高,时间复杂度平均情况下为O(n log n)。
    • 缺点:
      • 不稳定。

    6. 堆排序 (Heap Sort)

    解题思路:
    • 构建最大堆(或最小堆),将堆顶元素与最后一个元素交换,然后将堆的大小减一并重新维护堆的性质。
    实现代码:
    public class HeapSort {
        public static 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 temp = arr[i];
                arr[i] = arr[largest];
                arr[largest] = temp;
    
                heapify(arr, n, largest);
            }
        }
    
        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);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    优缺点:
    • 优点:
      • 高效的原地排序算法,时间复杂度为O(n log n)。
    • 缺点:
      • 不稳定。

    7. 计数排序 (Counting Sort)

    解题思路:
    • 统计数组中每个元素的出现次数,然后根据元素值和出现次数重新构建数组。
    实现代码:
    public class CountingSort {
        public static void countingSort(int[] arr) {
            int n = arr.length;
    
            int max = arr[0];
            for (int i = 1; i < n; i++) {
                if (arr[i] > max)
                    max = arr[i];
            }
    
            int[] count = new int[max + 1];
            for (int i = 0; i <= max; i++)
                count[i] = 0;
    
            for (int i = 0; i < n; i++)
                count[arr[i]]++;
    
            for (int i = 1; i <= max; i++)
                count[i] += count[i - 1];
    
            int[] output = new int[n];
            for (int i = n - 1; i >= 0; i--) {
                output[count[arr[i]] - 1] = arr[i];
                count[arr[i]]--;
            }
    
            for (int i = 0; i < n; i++)
                arr[i] = output[i];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    优缺点:
    • 优点:
      • 适用于元素范围不大的情况,时间复杂度为O(n + k),k为最大元素值。
    • 缺点:
      • 对于元素范围很大的数据效率较低。

    8. 桶排序 (Bucket Sort)

    解题思路:
    • 将元素分配到不同的桶中,对每个桶中的元素进行排序,然后合并所有桶。
    实现代码:
    import java.util.ArrayList;
    import java.util.Collections;
    
    public class BucketSort {
        public static void bucketSort(int[] arr) {
            int n = arr.length;
            int max = arr[0];
            int min = arr[0];
    
            for (int i = 1; i < n; i++) {
                if (arr[i] > max)
                    max = arr[i];
                if (arr[i] < min)
                    min = arr[i];
            }
    
            int bucketCount = max - min + 1;
            ArrayList<ArrayList<Integer>> buckets = new ArrayList<>(bucketCount);
    
            for (int i = 0; i < bucketCount; i++)
                buckets.add(new ArrayList<>());
    
            for (int i = 0; i < n; i++) {
                int bucketIndex = (arr[i] - min) * (bucketCount - 1) / (max - min);
                buckets.get(bucketIndex).add(arr[i]);
            }
    
            int index = 0;
            for (int i = 0; i < bucketCount; i++) {
                Collections.sort(buckets.get(i));
                for (int j = 0; j < buckets.get(i).size(); j++)
                    arr[index++] = buckets.get(i).get(j);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    优缺点:
    • 优点:
      • 适用于元素分布均匀的情况,时间复杂度为O(n + k),k为桶的个数。
    • 缺点:
      • 占用较多内存。

    总结和推荐

    • 推荐的排序算法: 归并排序和快速排序
    • 归并排序和快速排序都是高效的排序算法,时间复杂度为O(n log n),适用于各种规模的数据集。
    • 归并排序是稳定的,但需要额外的内存空间,适用于所有数据类型。
    • 快速排序是不稳定的,但在实践中通常比归并排序更快,适用于大规模数据集。

    这里推荐归并排序作为首选,因为它是稳定的且不会对原始数据造成修改。如果在内存受限的情况下考虑,可以选择快速排序。Bubble Sort、Selection Sort 和 Insertion Sort 适用于小规模数据集或教学目的,不推荐用于实际应用。

  • 相关阅读:
    探究-ping指令的使用
    MySQL中比较运算符的使用
    信号完整性测试,关于SMA装配的细节,很多人都忽视了
    智慧社区解决方案的服务形式有哪些
    科学计算与仿真-高斯牛顿法的非线性最小二乘问题简单介绍与应用
    Java 入门练习(31 - 35)
    Objective-C 基础教程第五章,复合
    spring mvc 上传文件出错,Required request part ‘file‘ is not present
    java流知识小结
    springcloudalibaba架构(28):分布式事务解决方案
  • 原文地址:https://blog.csdn.net/2302_79769114/article/details/133631589