什么是插入排序?
插入排序(Insertion Sort) 是一种简单且逐步构建有序序列的排序算法。它的思想是将数组分为两部分:已排序的部分和未排序的部分。初始时,已排序部分只包含数组的第一个元素,然后逐步将未排序部分的元素插入到已排序部分的正确位置,直到整个数组有序为止。
插入排序的详细步骤
1、从数组的第二个元素开始,将其视为待插入的元素。
2、将待插入元素与已排序部分的元素进行比较,从已排序部分的末尾开始。
3、如果待插入元素小于已排序部分的某个元素,则将该元素向右移动一位,为待插入元素腾出插入位置。
4、重复步骤 3,直到找到待插入元素的正确位置。
5、将待插入元素插入到正确的位置。
6、重复步骤 2 到 5,直到将所有元素插入到已排序部分。
举例说明
假设我们有以下待排序的数组:[5, 2, 9, 1, 5, 6]。
第一轮: 将数组中的第一个元素(5)视为已排序部分,然后将下一个元素(2)插入到已排序部分的正确位置。
排序后数组:[2, 5, 9, 1, 5, 6]
第二轮: 将数组中的第一个和第二个元素(2, 5)视为已排序部分,然后将下一个元素(9)插入到已排序部分的正确位置。
排序后数组:[2, 5, 9, 1, 5, 6]
第三轮: 将数组中的前三个元素(2, 5, 9)视为已排序部分,然后将下一个元素(1)插入到已排序部分的正确位置。
排序后数组:[1, 2, 5, 9, 5, 6]
第四轮: 将数组中的前四个元素(1, 2, 5, 9)视为已排序部分,然后将下一个元素(5)插入到已排序部分的正确位置。
排序后数组:[1, 2, 5, 5, 9, 6]
第五轮: 将数组中的前五个元素(1, 2, 5, 5, 9)视为已排序部分,然后将下一个元素(6)插入到已排序部分的正确位置。
排序后数组:[1, 2, 5, 5, 6, 9]
最终,整个数组变得有序:[1, 2, 5, 5, 6, 9]。
示例代码
#include <stdio.h>void InsertionSortFor(int arr[], int length);void InsertionSortWhile(int arr[], int length);void PrintArray(int arr[], int length);int main()
{int arr[] = {5, 2, 9, 1, 5, 6};/*不可以放在函数内部,当数组作为函数参数传递给函数时,数组参数会被转换为指针类型,因此在函数内部无法通过sizeof操作符获取数组的长度。*/int length = sizeof(arr) / sizeof(arr[0]);printf("原始数组:");PrintArray(arr, length);InsertionSortFor(arr, length);printf("排序后的数组:");PrintArray(arr, length);return 0;
}void InsertionSortFor(int arr[], int length)
{int i, j, key;for (i = 1; i < length; i++){key = arr[i];// 从当前位置向前遍历已排序的子数组,找到合适的插入位置for (j = i - 1; j >= 0 && arr[j] > key; j--){arr[j + 1] = arr[j]; // 向右移动元素}arr[j + 1] = key; // 插入元素到正确位置}
}void InsertionSortWhile(int arr[], int length)
{int i, j, key;for (i = 1; i < length; i++){key = arr[i];j = i - 1;// 将比 key 大的元素向右移动while (j >= 0 && arr[j] > key){arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}
}void PrintArray(int arr[], int length)
{int i;for (i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n");
}