排序算法之插入排序
直接插入排序
直接插入排序原理
直接插入排序也就是在未排序序列中,构建一个子排序序列,然后直到全部数据排序完成。它需要增加一个哨兵岗,放入待比较的值,让它和后面已经拍好序的序列进行比较,然后找到合适的位置插入。也就是将待排序的数,插入到已经排序的序列中合适的位置。
Insertion Sort 和打扑克牌时,从牌桌上逐一拿起扑克牌,在手上排序的过程相同。
举例:
Input: {5 2 4 6 1 3}。
首先拿起第一张牌, 手上有 {5}。
拿起第二张牌 2, 把 2 insert 到手上的牌 {5}, 得到 {2 5}。
拿起第三张牌 4, 把 4 insert 到手上的牌 {2 5}, 得到 {2 4 5}。
以此类推。
直接插入排序的重点在增加一个哨兵位,哨兵依次和待比较数的前一个数据比较,大数靠右移动,然后找到哨兵中值的插入位置。每一轮结束后,得到一个从开始到待比较数位置的一个有序序列。
m_list = [1,9,8,5,6,7,4,3,2] nums = [0]+m_list sentinel,*origin=nums print(nums,sentinel,origin)#哨兵位,待比较数字 length = len(nums) for i in range(2,length):#从2开始 nums[0]=nums[i]#放置哨兵 j = i -1 if nums[j] > nums[0]:#数字大的右移,找到插入的位置 while nums[j] > nums[0]: print(nums) nums[j+1] = nums[j]#依次右移 j-=1 print(nums) nums[j+1]=nums[0]#将哨兵插入,注意在插入右侧要+1 print(nums) 结果为: [0, 1, 9, 8, 5, 6, 7, 4, 3, 2] 0 [1, 9, 8, 5, 6, 7, 4, 3, 2] [8, 1, 9, 8, 5, 6, 7, 4, 3, 2] [8, 1, 9, 9, 5, 6, 7, 4, 3, 2] [5, 1, 8, 9, 5, 6, 7, 4, 3, 2] [5, 1, 8, 9, 9, 6, 7, 4, 3, 2] [5, 1, 8, 9, 9, 6, 7, 4, 3, 2] [5, 1, 8, 8, 9, 6, 7, 4, 3, 2] [6, 1, 5, 8, 9, 6, 7, 4, 3, 2] [6, 1, 5, 8, 9, 9, 7, 4, 3, 2] [6, 1, 5, 8, 9, 9, 7, 4, 3, 2] [6, 1, 5, 8, 8, 9, 7, 4, 3, 2] [7, 1, 5, 6, 8, 9, 7, 4, 3, 2] [7, 1, 5, 6, 8, 9, 9, 4, 3, 2] [7, 1, 5, 6, 8, 9, 9, 4, 3, 2] [7, 1, 5, 6, 8, 8, 9, 4, 3, 2] [4, 1, 5, 6, 7, 8, 9, 4, 3, 2] [4, 1, 5, 6, 7, 8, 9, 9, 3, 2] [4, 1, 5, 6, 7, 8, 9, 9, 3, 2] [4, 1, 5, 6, 7, 8, 8, 9, 3, 2] [4, 1, 5, 6, 7, 8, 8, 9, 3, 2] [4, 1, 5, 6, 7, 7, 8, 9, 3, 2] [4, 1, 5, 6, 7, 7, 8, 9, 3, 2] [4, 1, 5, 6, 6, 7, 8, 9, 3, 2] [4, 1, 5, 6, 6, 7, 8, 9, 3, 2] [4, 1, 5, 5, 6, 7, 8, 9, 3, 2] [3, 1, 4, 5, 6, 7, 8, 9, 3, 2] [3, 1, 4, 5, 6, 7, 8, 9, 9, 2] [3, 1, 4, 5, 6, 7, 8, 9, 9, 2] [3, 1, 4, 5, 6, 7, 8, 8, 9, 2] [3, 1, 4, 5, 6, 7, 8, 8, 9, 2] [3, 1, 4, 5, 6, 7, 7, 8, 9, 2] [3, 1, 4, 5, 6, 7, 7, 8, 9, 2] [3, 1, 4, 5, 6, 6, 7, 8, 9, 2] [3, 1, 4, 5, 6, 6, 7, 8, 9, 2] [3, 1, 4, 5, 5, 6, 7, 8, 9, 2] [3, 1, 4, 5, 5, 6, 7, 8, 9, 2] [3, 1, 4, 4, 5, 6, 7, 8, 9, 2] [2, 1, 3, 4, 5, 6, 7, 8, 9, 2] [2, 1, 3, 4, 5, 6, 7, 8, 9, 9] [2, 1, 3, 4, 5, 6, 7, 8, 9, 9] [2, 1, 3, 4, 5, 6, 7, 8, 8, 9] [2, 1, 3, 4, 5, 6, 7, 8, 8, 9] [2, 1, 3, 4, 5, 6, 7, 7, 8, 9] [2, 1, 3, 4, 5, 6, 7, 7, 8, 9] [2, 1, 3, 4, 5, 6, 6, 7, 8, 9] [2, 1, 3, 4, 5, 6, 6, 7, 8, 9] [2, 1, 3, 4, 5, 5, 6, 7, 8, 9] [2, 1, 3, 4, 5, 5, 6, 7, 8, 9] [2, 1, 3, 4, 4, 5, 6, 7, 8, 9] [2, 1, 3, 4, 4, 5, 6, 7, 8, 9] [2, 1, 3, 3, 4, 5, 6, 7, 8, 9] [2, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def insertion_sort(lst): for i in range(1, len(lst)): temp = lst[i] j = i - 1 while j >= 0 and temp < lst[j]: lst[j + 1] = lst[j] j -= 1 lst[j + 1] = temp return lst a = [1,5,2,6,7,9] insert_sort(a) 结果为: [1, 2, 5, 6, 7, 9] def insert_sort(lst): n=len(lst) if n==1: return lst#如果列表只有一个元素,直接返回。 for i in range(1,n): for j in range(i,0,-1): if lst[j]<lst[j-1]: lst[j],lst[j-1]=lst[j-1],lst[j] else: break return lst a = [1,5,2,6,7,9] insert_sort(a) 结果为: [1, 2, 5, 6, 7, 9]
直接插入排序最好的情况是正好升序,比较迭代次数n-1次。
最差的情况则是正好降序,比较迭代,1,2,3,……n-1即n(n-1)/2.
它使用两层嵌套循环, 时间复杂度为n的平方。直接插入排序是一种稳定的排序算法,一般使用在小规模的数据比较中。当数据大的时候,操作耗时会很大, 这个时候可以使用二分查找来提高效率,也就是二分查找排序。
二分查找排序