当前位置:   article > 正文

java算法:插入排序_快速排序算法

快速排序算法

基本使用

插入排序是一种简单直观的排序算法,它的工作原理是将待排序的数组分为已排序和未排序两部分,逐步将未排序部分的元素插入到已排序部分中的正确位置,直到整个数组有序。

插入排序的详细步骤:

  • 初始状态:将数组的第一个元素视为已排序部分,其余元素视为未排序部分。
  • 遍历未排序部分:从数组的第二个元素开始,逐个遍历未排序部分的元素。
  • 插入操作:将当前遍历到的元素插入到已排序部分的正确位置。为了找到正确的位置,从当前元素开始,逐个将已排序部分中的元素向后移动,直到找到合适的位置插入当前元素。
  • 重复步骤2和3:重复执行遍历未排序部分和插入操作,直到未排序部分的所有元素都被插入到已排序部分。
public class InsertionSort {
    public static void main(String[] args) {
        int[] arr = {7, 2, 1, 6, 8, 5, 3, 4};
        insertionSort(arr);
        System.out.println("Sorted array: " + Arrays.toString(arr));
    }

    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;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

插入排序的时间复杂度为O(n^2),其中n是数组的长度。它是一种稳定的排序算法,并且在小规模数据或部分有序的数据上表现良好。然而,在处理大规模数据时,插入排序的性能可能不如其他更高效的排序算法。

优缺点

优点:

  • 简单易实现: 插入排序算法的实现相对简单,易于理解和编写。
  • 原地排序: 插入排序只需要使用常数级别的额外空间,可以在原地进行排序,不需要额外的辅助空间。
  • 稳定性: 插入排序是一种稳定的排序算法,相等元素的相对顺序在排序后不会改变。

缺点:

  • 较慢的平均和最坏时间复杂度:插入排序的平均时间复杂度为 O ( n 2 ) O(n^2) O(n2),最坏情况下的时间复杂度也是 O ( n 2 ) O(n^2) O(n2),其中n是待排序元素的数量。这使得插入排序在处理大规模数据时效率较低。
  • 对逆序数据的排序效率低:如果待排序的数据已经部分有序或者是逆序的,插入排序的效率会明显降低。当逆序度较高时,需要进行大量的元素移动操作,导致性能下降。
  • 不适用于大规模数据: 由于插入排序的时间复杂度较高,它在处理大规模数据时的性能表现不如其他更高级的排序算法(如快速排序、归并排序等)。
  • 不适用于链式结构: 插入排序需要频繁地访问和移动元素,对于链式结构来说,访问和移动的成本较高,因此不适用于链表等非随机访问结构的排序。

尝试优化

插入排序是一种简单但效率较低的排序算法,但可以通过一些优化策略来提高其性能。

二分查找插入

在传统的插入排序中,为了找到当前元素的正确插入位置,需要逐个比较已排序部分中的元素。然而,我们可以使用二分查找的方法来减少比较的次数。具体步骤如下:

  • 将当前元素与已排序部分的中间元素进行比较。
  • 如果当前元素小于中间元素,则继续在已排序部分的前半部分进行二分查找。
  • 如果当前元素大于等于中间元素,则继续在已排序部分的后半部分进行二分查找。最终找到插入位置后,将已排序部分中插入位置后的元素都向后移动一位,并将当前元素插入到正确位置。

使用二分查找插入可以减少比较的次数,从而提高插入排序的性能。这种优化方法将插入排序的时间复杂度降低到 O ( n l o g n ) O(nlogn) O(nlogn)

public class InsertionSort {
    public static void main(String[] args) {
        int[] arr = {7, 2, 1, 6, 8, 5, 3, 4};
        insertionSort(arr);
        System.out.println("Sorted array: " + Arrays.toString(arr));
    }

    public static void insertionSort(int[] arr) {
        int n = arr.length;
        for (int i = 1; i < n; i++) {
            int key = arr[i]; // 当前要插入的元素
            int j = binarySearch(arr, key, 0, i - 1); // 使用二分查找找到插入位置

            // 将已排序部分中插入位置后的元素都向后移动
            System.arraycopy(arr, j, arr, j + 1, i - j);

            // 插入当前元素到正确的位置
            arr[j] = key;
        }
    }

    public static int binarySearch(int[] arr, int key, int start, int end) {
        while (start <= end) {
            int mid = start + (end - start) / 2;
            if (arr[mid] == key) {
                return mid;
            } else if (arr[mid] < key) {
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        return start;
    }
}
  • 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

减少交换操作

在传统的插入排序中,为了将当前元素插入到正确的位置,需要将较大的元素逐个向后移动,直到找到合适的位置。然而,我们可以通过将较大的元素向右移动一位,并将当前元素直接插入到正确位置来减少交换操作。具体步骤如下:

  • 将当前元素存储在临时变量中。
  • 向右移动较大的元素,直到找到合适的位置。
  • 将当前元素插入到正确的位置。

这种优化方法减少了交换操作的次数,从而提高了插入排序的性能。

public class InsertionSort {
    public static void main(String[] args) {
        int[] arr = {7, 2, 1, 6, 8, 5, 3, 4};
        insertionSort(arr);
        System.out.println("Sorted array: " + Arrays.toString(arr));
    }

    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;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/990068
推荐阅读
相关标签
  

闽ICP备14008679号