插入排序
简介
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法描述
● 从第一个元素开始,该元素可以认为已经被排序;
● 取出下一个元素,在已经排序的元素序列中从后向前扫描;
● 如果该元素(已排序)大于新元素,将该元素移到下一位置;
● 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
● 将新元素插入到该位置后;
● 重复步骤2~5。
动图演示
算法分析
- 最坏及平均情况均需比较(n-1)+(n-2)+(n-3)+…+3+2+1=n(n-1)/2;时间复杂度为0(n²),最好的情况时间复杂度O(n)。
- 此排序算法适用于大部分数据已经排过序或已排序数据库新增数据后进行排序的情况。
- 插入数据排序算法会造成数据的大量迁移,所以建议在链表上使用。
代码实现
"""
插入排序的关键点:
1、采用双层循环:时间复杂度也是O(n²)
(1)外层循环表示的是排序的趟数,n个数字需要n - 1
趟,因此,外层循环的次数是n - 1次;同时也代表数的位置。
(2)内层循环表示的是每一趟排序的数字。
根据插入排序的思想,第i趟排序时,有序数组中的数字就有i个,就需要进行i次比较,因此循环i次。
注意采用的是从后往前进行比较。
2、从后往前扫描的时候,如果必须插入的数大于有序数组中当前位置的数,则有序数组中的数和它之后的数均往后移一个位置
,否则,把插入的数插入到有序数组中。(稳定排序)
插入vs冒泡:
注:
插入排序的有序队列用到了冒泡算法
区别:
升序情况下:
冒泡:有序队列在后,无序队列在前,
插入:有序队列在前,无序队列在后
"""
def insert_sort_1(arr):
for i in range(1, len(arr)):
preindex = i - 1
current = arr[i]
while preindex >= 0 and arr[preindex] > current:
# 当有序区的元素大于抽到的元素时,将大于该元素的所有有序区元素向后移一位
arr[preindex + 1] = arr[preindex]
preindex -= 1
arr[preindex + 1] = current # 将抽到的元素插入到正确位置
return arr
def insert_sort_2(arr):
for i in range(len(arr) - 1):
for j in range(i, -1, -1):
if arr[j + 1] < arr[j]:
arr[j + 1], arr[j] = arr[j], arr[j + 1]
else:
break
return arr
def insert_sort(arr):
for i in range(1, len(arr)):
for j in range(i, 0, -1):
if arr[j - 1] > arr[j]:
arr[j - 1], arr[j] = arr[j], arr[j - 1]
else:
break
return arr
if __name__ == '__main__':
numbers1 = [2, 1, 5, 6, 9, 8, 7, 1, 0, 6, 4, 7, 10]
print(insert_sort_1(numbers1))
numbers2 = [2, 1, 9, 8, 5, 6, 7, 4, 0, 3, 4]
print(insert_sort_2(numbers2))
numbers = [9, 6, 8, 1, 5, 74, 56, 9, 8]
print(insert_sort(numbers))