"""
插入排序思想:
每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。
经典的插入排序:直接插入排序、折半插入排序、希尔排序
待排序表L[1...n]在某次排序过程中的某一时刻状态如下“
有序序列L[1...i-1] L[i] 无序序列L[i+1....n]
为了实现将元素L(i)插入到已有序的子序列L[1...i-1]中,需执行以下几个步骤:
1)、查找出L(i) 在L[1...i-1]中的插入位置k
2)、将L[k...i-1]的所有元素全部后移一个位置
3)、将L[i]复制到L[k]
为了实现对L[1...n]的排序,可以将L(2)~L(n)依次插入到前面已排好序的子序列中,初始假定L[1]是一个已排好序的子序列。
"""
def insert_sort(nums):
size = len(nums)
for i in range(1, size):
# temp 变量指向尚未排好序的元素(从第二个开始)
temp = nums[i]
# j指向前一个元素的下标
j = i - 1
# temp与前一个元素比较,若temp较小则前一个元素后移,j自减,继续比较
while j >= 0 and temp < nums[j]:
nums[j+1] = nums[j]
j = j - 1
# temp 所指向元素的最终位置
nums[j+1] = temp
return nums
"""
折半插入排序:当排序表为顺序存储的线性表时,可以采用折半插入排序方法:
即先折半查找出元素的的待插入位置,然后在统一地移动待插入位置之后的所有元素。
"""
def insert_two_devide_sort(nums):
size = len(nums)
for i in range(1, size):
# 将nums[i]暂存到temp
temp = nums[i]
# 设置折半查找的范围 先折半查找出元素的的待插入位置
low = 0
high = i - 1
while low <= high:
mid = (low + high)//2
if nums[mid] > temp:
high = mid - 1
else:
low = mid + 1
# 然后在统一地移动待插入位置之后的所有元素
j = i - 1
while j >= high + 1:
nums[j+1] = nums[j]
j = j - 1
nums[high+1] = temp
return nums
"""
希尔排序(缩小增量排序算法):
算法基本思想:先将待排序表分割成若干个形如L[i, i+d, i+2d, ...,i+kd]的‘特殊’子表。
分别进行直接插入排序,当整个表中的元素已呈‘基本有序’时,再对全体记录进行一次直接插入排序。
希尔排序的排序过程如下:
先取一个小于n的步长d1,把表中的全部记录分成d1个组,所有记录为d1的倍数的记录放在同一个组中,在各个组中进行直接插入排序;
然后取第二个步长d2<d1,重复上述过程,知道所取到的dt=1,即所有的记录已放在同一组中,再进行直接插入排序,由于此时已经具
有较好的局部有序性,故可以很快的得到最终结果。
"""
def shell_sort(nums):
"""
与直接插入排序相比:1、前后记录位置的增量是dk,不是1
:param nums:
:return:
"""
size = len(nums)
dk = size//2
while dk >= 1:
for k in range(dk):
for i in range(k+dk, size, dk):
temp = nums[i]
j = i - dk
while j >= k and temp < nums[j]:
nums[j+dk] = nums[j]
j = j - dk
nums[j+dk] = temp
dk = dk // 2
return nums
if __name__ == '__main__':
lists = [3, 5, 1, 2, 4]
print(lists)
print(insert_sort(lists))
print(insert_two_devide_sort(lists))
print(shell_sort(lists))