1、原理
插入排序(Insertion Sort)是一种简单直观的排序算法,其原理可以简述如下:
1.分已排序区间和未排序区间: 将数组分为已排序区间和未排序区间。初始时,已排序区间只包含数组的第一个元素,而未排序区间包含除第一个元素之外的所有元素。
2.依次将未排序区间中的元素插入到已排序区间中的合适位置: 从未排序区间取出第一个元素,将它插入到已排序区间的合适位置,使得已排序区间仍然保持有序。插入的方式是从已排序区间的末尾开始向前比较,找到插入位置后将元素插入其中。
3.重复步骤2直至未排序区间为空: 重复执行上述插入操作,直到未排序区间中的所有元素都被插入到已排序区间中,即整个数组排序完成。
评价:插入排序是一种稳定的排序算法,其时间复杂度为O(n^2),适用于小型数据集或者已接近有序的数据集。由于其简单直观的实现方式,插入排序通常被用作其他高级排序算法的优化手段,例如快速排序的递归基础情况或归并排序的小规模排序。
2、代码展示
实现一个数组的元素升序排序
#include <stdio.h>
void Insert_sort(int arr[], int size)
{
int i = 0;
int j = 0;
int temp = 0;//存放未排好序区间的第一个数
for (i = 1; i < size; i++)
{
temp = arr[i];
j = i - 1;//存放已排好序区间的最后一个数下标
while (j >= 0 && arr[j] > temp)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
void Print(int arr[], int size)
{
for (int i = 0; i < size; i++)
{
printf("%-3d", arr[i]);
}
printf("\n");
}
int main()
{
int arr[10] = { 5,1,3,8,2,6,4,9,10,7 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("排序前:");
Print(arr, len);
Insert_sort(arr, len);
printf("排序后:");
Print(arr, len);
return 0;
}
输出结果:
3、解析代码
变量temp
是用来临时存放未排好序区间的第一个数,j = i - 1;
用来存放已排好序区间的最后一个数下标,while
循环是实现从已排序区间的末尾开始向前比较元素大小。
(1)第一轮排序:
首先确定5是已排好序的,我们将1拿来进行插入排序,1进行第一轮排序的第一次排序和5比较,显然5比1大,这是第一次,也是本轮的最后一次比较,所以将1插入到5前面,此时的序列是1,5,3,8,2,6,4,9,10,7然后进入第二轮排序。
(2)第二轮排序:
首先在第一轮排序中1,5这前两位是排好序的(即已排序区间),我们现在将3拿出来和前面排好序的部分进行对比调位,首先在本轮的第一次排序和5比较,显然5比3大,所以直接将3插入到5前面,此时的序列是1,3,5,8,2,6,4,9,10,7,第二次比较,3和1比,显然3比1大,第二次排序仍是1,3,5,8,2,6,4,9,10,7,然后结束本轮排序进入第三轮排序。
(3)第三轮排序:
将8和前面排好序的三个数(即已排序区间)进行对比调位,本轮的第一次比较,8比5大,所以排序原地不动,排序为1,3,5,8,2,6,4,9,10,7,结束本轮排序进入第四轮排序。
(4)剩下的以此类推。
4、适用场景
1.小型数据集: 插入排序在小型数据集上表现良好,因为其时间复杂度为O(n^2),在数量较少的情况下效率较高。
2.几乎已排序的数据: 当数据集接近有序时,插入排序的性能较好。因为插入排序每次只需要将一个元素插入到已排序部分的合适位置,对于几乎已排序的数据,插入操作的次数较少,性能相对较高。
3.稳定性要求: 插入排序是一种稳定的排序算法,即相同元素的相对位置在排序后不会改变。如果对排序结果的稳定性有要求,插入排序是一个不错的选择。
4.部分有序的数据集: 对于部分有序的数据集,插入排序的效率较高。部分有序的数据集意味着某些元素已经处于相对有序的状态,插入排序可以利用这种部分有序性,快速完成排序。
5.排序过程可以被分步进行: 插入排序是一种在线排序算法,可以逐步地将元素插入到已排序部分,因此适用于需要逐步处理数据的场景。
结论:插入排序在处理小型数据集、接近有序的数据集、部分有序的数据集以及对排序稳定性要求较高的情况下表现良好。然而,在处理大型数据集时,插入排序的效率较低,不如一些高效的排序算法如快速排序或归并排序。
总结:
插入排序的核心思想是每次从未排序区间中取出一个元素,然后将其插入到已排序区间中的合适位置,使得已排序区间不断扩大,未排序区间不断减小,直至全部元素都被插入到已排序区间中。
那么写到这里,本节内容就结束了,这篇博客花费了很长时间,但写完有满满的成就感,希望能帮助到大家,如果文章有不足的地方,欢迎在评论区留言指正,我们一起学习交流!
希望能得到大家的关注、点赞、评论、收藏! 你的支持是我最大的动力!!