第八章 排序 二、插入排序

目录

一、算法思想

二、例子

三、代码实现

四、空间复杂度

五、时间复杂度

1、最好的情况

2、最坏的情况

六、优化(折半插入排序)

七、总结


一、算法思想

每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到所有记录插入完成。

二、例子

1、假设我们有以下序列(我们进行升序排序)

第八章 排序 二、插入排序_第1张图片

2、插入排序直接从第二个数开始,我们检查38前的所有数,找到比38大的数,将其右移一位。

第八章 排序 二、插入排序_第2张图片

3、并将38放入49的前面。

第八章 排序 二、插入排序_第3张图片

4、接下来查看65前面所有的值,并与65进行对比。发现65比前面所有的值都要大,97同样如此。

第八章 排序 二、插入排序_第4张图片

5、然后是检查76前面的所有值,发现97比76大,于是97右移。

第八章 排序 二、插入排序_第5张图片

6、接着与65进行对比,发现76大于65,于是把76插入97前面。并且我们开始检查13前面的所有值。

第八章 排序 二、插入排序_第6张图片

7、每次对比一个数,如果这个数比13大,就将此数右移一位。

97>13

第八章 排序 二、插入排序_第7张图片

76>13

第八章 排序 二、插入排序_第8张图片

65>13

第八章 排序 二、插入排序_第9张图片

49>13

第八章 排序 二、插入排序_第10张图片

38>13

第八章 排序 二、插入排序_第11张图片

8、再往前已经没有数了,所以将13插入到38的前面

第八章 排序 二、插入排序_第12张图片

9、数字27同理

第八章 排序 二、插入排序_第13张图片

10、最后我们比较49前面的数,由于我们的判定条件是如果此数比49大,则右移,所以这个49只能移动到下标为3的49的前面。(保证了算法的稳定性)

第八章 排序 二、插入排序_第14张图片

三、代码实现

#include 

void InsertSort(int arr[],int n){
    int temp,j;
    for (int i = 1; i < n; ++i) {//遍历从第二个数开始的所有数
        if (arr[i-1]>arr[i]){//如果它的前一个数比它大
            temp = arr[i];//将此数放入缓存变量
            for (j = i-1; j >= 0 && arr[j] > temp; --j) {//依次和前面的数进行比较
                arr[j+1] = arr[j];//如果比此数大,则右移一位
            }
            arr[j+1] = temp;//最后将此数插入最后一个比它的的数后面
        }
    }
}

int main(){
    int count,arr[10];
    scanf("%d",&count);//输入数组长度
    for (int i = 0; i < count; ++i) {
        scanf("%d",&arr[i]);//输入数组
    }
    InsertSort(arr,count);//调用排序函数
    for (int i = 0; i < count; ++i) {
        printf("%d ",arr[i]);//输出数组
    }
    return 0;
}

验证:

第八章 排序 二、插入排序_第15张图片

四、空间复杂度

O(1);

五、时间复杂度

1、最好的情况

序列本来就是有序的,把每个数据都检查一次。

得到的时间复杂度为O(n);

2、最坏的情况

序列为逆序,而我们要进行顺序排序。

第一个数要比较0次,移动0次;

第二个数要比较1次,移动1次;

第三个数要比较2次,移动2次;

。。。。。。。。。

依此类推

第N个数要比较N-1次,移动N-1次;

所以最坏时间复杂度为2*(1+2+3+4+。。。+(n-1)),最后得O(n^2);

六、优化(折半插入排序)

在时间复杂度上没有质的飞跃,只是减少了一些比较的次数。

时间复杂度仍然为O(n^2);

第八章 排序 二、插入排序_第16张图片

七、总结

第八章 排序 二、插入排序_第17张图片

你可能感兴趣的:(数据结构学习,数据结构)