插入排序
原理
一句话概括:依次选择一个待排序的数据,插入到前边已排好序的序列中。
1.从数组的第二个数据开始往前比较,即一开始用第二个数和他前面的一个比较,如果 符合条件(比前面的大或者小,自定义),则让他们交换位置。
2.然后再用第三个数和第二个比较,符合则交换,但是此处还得继续往前比较,比如有 5个数8,15,20,45, 17,17比45小,需要交换,但是17也比20小,也要交换,当不需 要和15交换以后,说明也不需要和15前面的数据比较了,肯定不需要交换,因为前 面的数据都是有序的。
3.重复步骤二,一直到数据全都排完。
性能
时间复杂度为O(N^2),空间复杂度为O(1)。算法是稳定的,比较次数和交换次数都与初始序列有关。
优化
直接插入排序每次往前插入时,是按顺序依次往前找,可在这里进行优化,往前找合适的插入位置时采用二分查找的方式,即折半插入(二分查找插入)。
折半插入排序相对直接插入排序而言:平均性能更快,时间复杂度降至O(NlogN),排序是稳定的,但排序的比较次数与初始序列无关,总是需要foor(log(i))+1次排序比较。
使用场景
当数据基本有序时,采用插入排序可以明显减少数据交换和数据移动次数,进而提升排序效率。
算法适用于少量数据的排序。
直接插入排序
def insertsort(mylist):
length = len(mylist)
if length <= 1:
return mylist
# 只有列表长度大于1时才需要比较插入,i为列表的第i个元素,需要依次和前面的i-1个数做比较插入
for i in range(1, length):
j = i - 1
# 如果当前值小于前一个元素,将当前值存储于一个临时变量中,将前一个元素后移一位
if mylist[i] < mylist[j]:
tmp = mylist[i]
mylist[i] = mylist[j]
# 继续将tmp和更前面一位元素比较,如果元素值比tmp值大,则后移一位
j -= 1
while j >= 0 and tmp < mylist[j]:
mylist[j+1] = mylist[j]
j -= 1
mylist[j+1] = tmp
return mylist
mylist = [48, 38, 65, 97, 76, 13, 27, 49]
print(insertsort(mylist))
def insert_sort(lists):
count = len(lists)
if length <= 1:
return mylist
for i in range(1, count):
# 将当前值存入临时变量中
key = lists[i]
j = i - 1
while j >= 0:
# 如果当前值小于前一个元素,将前一个元素后移一位
if lists[j] > key:
lists[j + 1], lists[j] = lists[j], key
j -= 1
return lists
mylist = [48, 38, 65, 97, 76, 13, 27, 49]
print(insert_sort(mylist))