插入排序

插入排序:
        类似于打扑克
        把列表[0]当作一个有序数列,将第2个数插入到序列中正确的位置,
        把列表[0,  1]当作一个有序数列,将第3个数插入到序列中正确的位置
        ...

时间复杂度:O(n^2)

适用场景:每次插入都要移动数据,且只移动1位,在小规模数据集或”基本有序“数据集情况下,
                插入排序会比较高效,但若数据集比较大时,效率就会比较低,优化方案:希尔排序

剖析:插入到某个位置(index),就说明[index,  end_index]  区间内的值都需要  +  1

思路一:
        1、从  [0,  end_index]  先找到  end_index  +  1  正确的位置(index)
        2、将  [index,  end_index]  的值都向后移动一位
        3、将  end_index  +  1  的值  赋值给  index
        迭代实现:

def insert_sort_iteration(datas):
    def _insert(index, data_index):
        next_data = datas[index]
        datas[index] = datas[data_index]
        for index in range(index, data_index):
            temp = datas[index + 1]
            datas[index + 1] = next_data
            next_data = temp

    length = len(datas)
    for j in range(1, length):
        data = datas[j]
        for i in range(0, j):
            if datas[i] > data:
                _insert(i, j)
                break
    return datas

        递归实现:

def insert_sort_recursion(datas):
    def _insert(index, data_index):
        next_data = datas[index]
        datas[index] = datas[data_index]
        for i in range(index, data_index):
            temp = datas[i + 1]
            datas[i + 1] = next_data
            next_data = temp

    def _find_right_position(end_index):
        target_index = end_index + 1
        if target_index == length:
            return
        target_data = datas[target_index]
        for index in range(0, target_index):
            if datas[index] > target_data:
                _insert(index, target_index)
                break
        _find_right_position(end_index + 1)

    length = len(datas)
    _find_right_position(0)
    return datas

        

思路二:
        将思路一中的  1、2  合并起来,即  ”边移动边找正确的位置“,
        ”挖坑“思想应用:
        要把  end_index  +  1  插入到  [0,  end_index]的正确位置中:
        将  end_index  +  1  挖出来放到一边,值记作  current,  如果前一个值大于  current,
        则把前一个值挖出填到坑中,然后再继续比较前面的值
        1、遇到比  current  小的,这时停止循环比较,把  current  填到坑中
        2、都没有比  current  小的,current  放在首位
        迭代实现:

def insert_sort_iteration2(datas):
    length = len(datas)
    for index in range(0, length):
        pre_index = index - 1
        current = datas[index]
        while pre_index >= 0:
            if datas[pre_index] <= current:
                break
            datas[pre_index + 1] = datas[pre_index]
            pre_index -= 1
        datas[pre_index + 1] = current
    return datas

        递归实现:

def insert_sort_recursion2(datas):
    def _move_insert(pre_index, target):
        if pre_index < 0 or datas[pre_index] <= target:
            datas[pre_index + 1] = target
            return
        datas[pre_index + 1] = datas[pre_index]
        _move_insert(pre_index - 1, target)

    length = len(datas)
    for index in range(0, length):
        _move_insert(index - 1, datas[index])

    return datas