插入排序(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
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");
}