重温经典排序算法之直接插入排序——图解+C/C++实现

1.直接插入排序算法原理

将n个元素的数列分为已经有序和无序两部分,循环的操作就是将无序数列的第一个元素与有序数列的元素从末尾往前逐个比较,将该元素插入到有序数列的合适位置中去,直到序列最后一个元素操作完毕为止。
如:假设序列array[6]={3,7,5,2,1,6},第二次比较后的数组变成array[]={3,5,7,2,1,6}。

2.算法性能分析

(1)时间复杂度

a.最好情况:原序列已经是正序排列,在此情况下,需要进行比较次数为(n-1),即

C = n 1 C=n-1

因此最好情况的时间复杂度为 O ( n ) O(n)

b.最差情况:原序列完全反序,在此情况下,需要进行比较次数为n(n-1)/2,赋值操作次数为n(n-1)/2+(n-1)次,即

C = n ( n 1 ) 2 C=\frac{n(n-1)}{2} M = n ( n 1 ) 2 + ( n 1 ) M=\frac{n(n-1)}{2}+(n-1)

因此最差情况的时间复杂度为 O ( n 2 ) O(n^2)
综上所述,直接插入排序算法的平均时间复杂度为:

O ( n 2 ) O(n^2)

(2)算法稳定性

插入排序是在一个已经有序的子序列基础上,一次插入一个元素。比较是从有序序列的末尾开始,即要插入的元素与已经有序序列的最大者比较,如果前者比后者大则直接插入在其后。如果一个有序序列中的数与插入元素相等,则把插入元素放在相等元素的后面。所以相等元素相对的前后位置没有发生改变。

因此,直接插入排序算法是一种稳定的算法。

3.图解分析

要排序的数组:[3,7,5,2,1,6]:
初始状态有序子序列为{3},无序子序列为{7,5,2,1,6}

初始状态
7
5
2
1
6
3

第一趟排序:将7插入有序子序列{3}的适当位置,构成新的有序子序列

第一趟排序
7
5
2
1
6
3
5
2
1
6
3
7

第二趟排序:将5插入有序子序列{3,7}的适当位置,构成新的有序子序列

第二趟排序
5
2
1
6
3
7
2
1
6
3
5
7

第三趟排序:将2插入有序子序列{3,5,7}的适当位置,构成新的有序子序列

第三趟排序
2
1
6
3
5
7
1
6
2
3
5
7

第四趟排序:将1插入有序子序列{2,3,5,7}的适当位置,构成新的有序子序列

第四趟排序
1
6
2
3
5
7
6
1
2
3
5
7

第五趟排序:将6插入有序子序列{1,2,3,5,7}的适当位置,构成新的有序子序列

第五趟排序
6
1
2
3
5
7
1
2
3
5
6
7
直接插入排序最后结果为:
1
2
3
5
6
7

4.C/C++实现

#include <iostream>
using namespace std;
void Insert_Sort(int arr[],int time)
{
    int j;//如果在for循环里定义j,j只在for循环里有效,则执行arr[j]=temp时会报错
    int temp;//设置临时变量
    for(int i=1;i<time;i++)
    {
        temp = arr[i];//记录每次无序区的第一个值
        for(j=i;j>0&&(arr[j-1]>temp);j--)//与有序区的数逐一比较,大于temp时该数后移1位
            arr[j] = arr[j-1];
        arr[j] = temp;
    }
}
int main()
{
    int arr[6] = {3,7,5,2,1,6};//这里根据需要可以任意改变数组
    int length = 6;//上述arr数组的长度
    Insert_Sort(arr,length);
    for(int i = 0;i<length;i++)
        cout<<arr[i]<<" ";//输出结果:1 2 3 5 6 7
    return 0;
}

输出结果为:
在这里插入图片描述
冒泡排序图解+C/C++实现戳这里!!
选择排序图解+C/C++实现戳这里!!

发布了20 篇原创文章 · 获赞 16 · 访问量 1291

猜你喜欢

转载自blog.csdn.net/SAMSARS/article/details/105197835