直接插入排序是一种最简单的插入排序
这里我们主要学习直接插入升序排序。

1.什么是插入排序:
每一趟将一个待排序的记录,按照其关键字的大小插入到有序队列的合适位置里,直到全部插入完成。
例子:
在打扑克牌的时候:
你手里有一张5,
再摸到一张4,比5小,插到5前面,
又摸到一张6,比5大,插到5后面,
再摸到一张7,比6大,插到6后面

这就是典型的直接插入排序,每次将一个新数据插入到有序队列中的合适位置里。

2.算法思想:
假设我们现在有一组待排序的序列 D0,D1,D2,…,Nn-1
(1)我们先将这个序列下标为0的元素D0视为个数为1的有序序列
(2)然后,我们将D1,D2,…,Nn-1插入到这个有序序列中。所以,我们需要一个外部循环,从下标 1 扫描到 n-1 。
(3)假设这是要将 Di 插入到前面有序的序列中,由前面所述,我们可知,插入Di时,前 i-1 个数肯定已经是有序了。
所以我们需要将Di 和D0 ~ Di-1 进行比较,确定要插入的合适位置。这就需要一个内部循环,我们一般是从后往前比较,即从下标 i-1 开始向 0 进行扫描。

3.python3代码实现:

# -*- coding: utf-8 -*-
"""
Created on Wed Jul 10 11:44:36 2019

@author: ZQQ
"""

def insertSort(input_list):
    n = len(input_list) # 计算待排序序列长度
    if n <= 1:          # 已有序,或为空,直接返回
        return input_list
    else:
        # 第一层循环表示插入的遍数
        for i in range(1,n): # i取 1,2,3,..., n-1
            # 当前待插入的元素
            current = input_list[i]
            # 已经有序元素的索引
            pre_index = i - 1
            while pre_index >= 0 and input_list[pre_index] > current:
                # 当 比较元素 > 当前元素, 则把比较元素后移
                input_list[pre_index + 1] = input_list[pre_index]
                # 往前选择下一个比较元素
                pre_index -= 1
            # 当 比较元素 < 当前元素,或不满足pre_index>=0,则将 当前元素 插入其后面
            input_list[pre_index + 1] = current
            print(input_list)
        return input_list          
            
input_list = [6, 4, 8, 9, 2, 3, 1]
print('排序前:', input_list)
sorted_list = insertSort(input_list)
print('排序后:', sorted_list)

实验结果:

python怎么返回一个序列最小元素的下标_数组

4.算法分析:
插入排序的适用场景:一个新元素需要插入到一组已经是有序的数组中,或者是一组基本有序的数组排序。

(1)比较性:排序时元素之间需要比较,所以为比较排序
(2)稳定性:从代码我们可以看出只有比较元素大于当前元素,比较元素才会往后移动,所以相同元素是不会改变相对顺序稳定排序
(3)时间复杂度:插入排序同样需要两次循坏一个一个比较,故时间复杂度为O(n^2)
(4)空间复杂度:只需要常数个辅助单元,所以空间复杂度为O(1)
(5)复杂性:简单
注:当数据正序时,执行效率最好,每次插入都不用移动前面的元素,时间复杂度为O(N)。
当数据反序时,执行效率最差,每次插入都要前面的元素后移,时间复杂度为O(N^2)。
所以,数据越接近正序,直接插入排序的算法性能越好。
平均情况:O(N^2)

5.算法优化:
因为在一个有序序列中查找一个插入位置,以保证有序序列的序列不变,所以可以使用二分查找,减少元素比较次数提高效率
二分查找是对于有序数组而言的,假设如果数组是升序排序的,那么,二分查找算法就是不断对数组进行对半分割,每次拿中间元素和目标数字进行比较,如果中间元素小于目标数字,则说明目标数字应该在右侧被分割的数组中,如果中间元素大于目标数字,则说明目标数字应该在左侧被分割的数组中。

# -*- coding: utf-8 -*-
"""
Created on Wed Jul 10 15:46:21 2019

@author: ZQQ
"""
~~~python
# -*- coding:utf-8 -*-
 
def BinarySearch(input_list, end, value):
    left = 0
    right = end - 1
    while left <= right:
        middle = left + (right - left) // 2
        if input_list[middle] >= value:
            right = middle - 1
        else:
            left = middle + 1
 
    return left if left < end else -1
 
def BinaryInsertSort(input_list):
    if len(input_list) == 0:
        return []
    result = input_list
    for i in range(1, len(input_list)):
        j = i - 1
        temp = result[i]
        insert_index = BinarySearch(result, i, result[i])
        if insert_index != -1:
            while j >= insert_index:
                result[j + 1] = result[j]
                j -= 1
            result[j + 1] = temp
    return result
 

input_list = [6, 4, 8, 9, 2, 3, 1]
print('排序前:', input_list)
sorted_list = BinaryInsertSort(input_list)
print('排序后:', sorted_list)