原文: https://www.programiz.com/dsa/insertion-sort

在本教程中,您将学习插入排序的工作原理。 此外,您还将找到使用 C,C++ ,Java 和 Python 进行插入排序的有效示例。

插入排序的工作方式与我们在纸牌游戏中对手牌进行排序的方式类似。

我们假设第一张卡片已经被排序,那么我们选择一个未排序的卡片。 如果未排序的卡片大于手中的卡片,则将其放置在右侧,否则放置在左侧。 同样,其他未排序的卡片也会被拿到正确的位置。

插入排序使用类似的方法。

插入排序是一种排序算法,它在每次迭代中将未排序的元素放置在其合适的位置。


插入排序如何工作?

假设我们需要对以下数组进行排序。

插入排序算法 - 图1

初始数组

  1. 假定数组中的第一个元素已排序。 取第二个元素并将其分别存储在key中。
    key与第一个元素进行比较。 如果第一个元素大于key,则将key放在第一个元素的前面。
    插入排序算法 - 图2
    如果第一个元素大于key,则将key放在第一个元素的前面。

  2. 现在,对前两个元素进行排序。
    取第三个元素并将其与左侧的元素进行比较。 将其放置在比其小的元素后面。 如果没有比它小的元素,则将其放在数组的开头。
    插入排序算法 - 图3
    将 1 放在开头

  3. 同样,将每个未排序的元素放在正确的位置。
    插入排序算法 - 图4
    将 4 放在 1 后面
    [
    插入排序算法 - 图5
    将 3 放在 1 后面,并对数组进行排序


插入排序算法

  1. insertionSort(array)
  2. mark first element as sorted
  3. for each unsorted element X
  4. 'extract' the element X
  5. for j <- lastSortedIndex down to 0
  6. if current element j > X
  7. move sorted element to the right by 1
  8. break loop and insert X here
  9. end insertionSort

Python,Java 和 C/C++ 示例

  1. # Insertion sort in Python
  2. def insertionSort(array):
  3. for step in range(1, len(array)):
  4. key = array[step]
  5. j = step - 1
  6. # Compare key with each element on the left of it until an element smaller than it is found
  7. # For descending order, change key<array[j] to key>array[j].
  8. while j >= 0 and key < array[j]:
  9. array[j + 1] = array[j]
  10. j = j - 1
  11. # Place key at after the element just smaller than it.
  12. array[j + 1] = key
  13. data = [9, 5, 1, 4, 3]
  14. insertionSort(data)
  15. print('Sorted Array in Ascending Order:')
  16. print(data)
  1. // Insertion sort in Java
  2. import java.util.Arrays;
  3. class InsertionSort {
  4. void insertionSort(int array[]) {
  5. int size = array.length;
  6. for (int step = 1; step < size; step++) {
  7. int key = array[step];
  8. int j = step - 1;
  9. // Compare key with each element on the left of it until an element smaller than
  10. // it is found.
  11. // For descending order, change key<array[j] to key>array[j].
  12. while (j >= 0 && key < array[j]) {
  13. array[j + 1] = array[j];
  14. --j;
  15. }
  16. // Place key at after the element just smaller than it.
  17. array[j + 1] = key;
  18. }
  19. }
  20. // Driver code
  21. public static void main(String args[]) {
  22. int[] data = { 9, 5, 1, 4, 3 };
  23. InsertionSort is = new InsertionSort();
  24. is.insertionSort(data);
  25. System.out.println("Sorted Array in Ascending Order: ");
  26. System.out.println(Arrays.toString(data));
  27. }
  28. }
// Insertion sort in C

#include <stdio.h>

// Function to print an array
void printArray(int array[], int size) {
  for (int i = 0; i < size; i++) {
    printf("%d ", array[i]);
  }
  printf("\n");
}

void insertionSort(int array[], int size) {
  for (int step = 1; step < size; step++) {
    int key = array[step];
    int j = step - 1;

    // Compare key with each element on the left of it until an element smaller than
    // it is found.
    // For descending order, change key<array[j] to key>array[j].
    while (key < array[j] && j >= 0) {
      array[j + 1] = array[j];
      --j;
    }
    array[j + 1] = key;
  }
}

// Driver code
int main() {
  int data[] = {9, 5, 1, 4, 3};
  int size = sizeof(data) / sizeof(data[0]);
  insertionSort(data, size);
  printf("Sorted array in ascending order:\n");
  printArray(data, size);
}
// Insertion sort in C++

#include <iostream>
using namespace std;

// Function to print an array
void printArray(int array[], int size) {
  for (int i = 0; i < size; i++) {
    cout << array[i] << " ";
  }
  cout << endl;
}

void insertionSort(int array[], int size) {
  for (int step = 1; step < size; step++) {
    int key = array[step];
    int j = step - 1;

    // Compare key with each element on the left of it until an element smaller than
    // it is found.
    // For descending order, change key<array[j] to key>array[j].
    while (key < array[j] && j >= 0) {
      array[j + 1] = array[j];
      --j;
    }
    array[j + 1] = key;
  }
}

// Driver code
int main() {
  int data[] = {9, 5, 1, 4, 3};
  int size = sizeof(data) / sizeof(data[0]);
  insertionSort(data, size);
  cout << "Sorted array in ascending order:\n";
  printArray(data, size);
}

复杂度

时间复杂度

  • 最坏情况的复杂度O(n^2)
    假设一个数组是升序的,并且您想按降序对其进行排序。 在这种情况下,最坏情况下的复杂度就会发生。
    每个元素都必须与其他每个元素进行比较,因此,对于每第n个元素,进行(n-1)个比较。
    因此,比较总数= n*(n-1) ~ n^2

  • 最佳情况复杂度O(n)
    当数组已经排序时,外循环运行n次数,而内循环则根本不运行。 因此,只有n个比较。 因此,复杂度是线性的。

  • 平均情况复杂度O(n^2)
    当数组的元素处于混乱顺序(既不升也不降)时,会发生这种情况。

空间复杂度

空间复杂度为O(1),因为使用了额外的变量key


插入排序应用

在以下情况下使用插入排序:

  • 数组包含少量元素
  • 仅剩下一些要排序的元素