一、插入排序:时间复杂度、原地排序
原理:可以想象成打扑克牌时候,发到手里的牌,我们一张一张拿起来插到手里牌的适当位置。
将待排序列表的第一个元素看作是一个有序序列(或叫有序区),然后从第二个元素开始,一直到最后一个元素,都看作无序区。现在从头到尾,一个一个的将无序区的元素,插到有序区的适当位置。
也就是说:刚开始时,我们手里(也就是有序区),只有一张牌,现在我们每次从无序区摸一张牌,插到自己手里牌的适当位置。
也就是说,将第一个元素看作是一个有序的列表,从第二个元素开始,将这个元素与有序区里的元素进行比较,找到合适的插入位置,同时,把插入位置后面的元素依次向后移一个位置,或者叫向右移一个位置。
具体做法:
1、将待排序列表的第一个元素看作是一个有序序列(有序区),第二个元素到最后一个元素,看作无序序列(无序区)。
2、取无序区里的第一个元素,比如a,将a与有序区最后一个元素进行比较,比如b,如果a>b,就把a放到b的后面,如果a<b,则把b向后移一个位置,然后再拿b前面那个数跟a进行比较,如果a还是比它小,就把b再往后移一个位置,把b前面的那个数也往自己原来的位置再向右移一个位置,以此类推,直到把a放到合适的位置,使得把a放进去之后,有序区依然是排好序的。
3、重复上个步骤,继续插入下个数据。
代码:
def insert_sort(li):
for i in range(1, len(li)): # i表示摸到的牌,它的下标
temp = li[i] # 摸到的牌
j = i - 1 # j表示手里的牌,它的下标
while j >= 0 and li[j] > temp:
li[j + 1] = li[j] # 手里的牌往右移一个位置
j -= 1
li[j + 1] = temp
l1 = [3, 2, 4, 1]
insert_sort(l1)
print(l1)
# 结果:
[1, 2, 3, 4]
查看每次插入排序的结果:
def insert_sort(li):
for i in range(1, len(li)): # i表示摸到的牌,它的下标
temp = li[i] # 摸到的牌
j = i - 1 # j表示手里的牌,它的下标
while j >= 0 and li[j] > temp: # 找到合适的插入位置
li[j + 1] = li[j] # 手里的牌往右移一个位置
j -= 1
li[j + 1] = temp
print(li) # !! 每次插入一个值后的结果
l1 = [3, 2, 4, 1]
print(l1)
insert_sort(l1)
# 结果:
[3, 2, 4, 1]
[2, 3, 4, 1]
[2, 3, 4, 1]
[1, 2, 3, 4]
解释:
[3, 2, 4, 1]
[2, 3, 4, 1]
[2, 3, 4, 1]
[1, 2, 3, 4]
首先第一行:表示待排序列表:[3, 2, 4, 1],其中,3是有序区
然后把2插进来,得到:[2, 3, 4, 1];其中,红色表示有序区
把4插进来,得到:[2, 3, 4, 1],
最后把1插进来,得到:[1, 2, 3, 4]