希尔排序算法动态图如下:
- 希尔排序算法思路
希尔排序算法本质上是对插入排序算法的改进,它是发现了当一串数基本有序的情况下,插入算法效率非常高,所以,希尔排序就根据这个特点,通过分段分批处理,让一串数慢慢的变的基本有序,直至最终有序
具体代码实现如下:
def shell_sort(datas):
count=0
gap=len(datas)//2
while gap>0:
index=0
for i in range(gap,len(datas)):
index+=1
temp=datas[i]
for j in range(i,0,-gap):
if temp<datas[j-gap]:
datas[j],datas[j-gap]=datas[j-gap],datas[j]
count+=1
else:
if j!=i:
datas[j]=temp
count+=1
break
print(f"当gap = {gap} 时,经过第 {index} 轮插入排序后的结果:",datas)
gap//=2
print(f"共经过 {count} 次交换或赋值操作")
return datas
if __name__=="__main__":
datas=[10,9,8,7,6,5,4,3,2,1,0]
datas=shell_sort(datas)
执行详细结果如下:
当gap = 5 时,经过第 1 轮插入排序后的结果: [5, 9, 8, 7, 6, 10, 4, 3, 2, 1, 0]
当gap = 5 时,经过第 2 轮插入排序后的结果: [5, 4, 8, 7, 6, 10, 9, 3, 2, 1, 0]
当gap = 5 时,经过第 3 轮插入排序后的结果: [5, 4, 3, 7, 6, 10, 9, 8, 2, 1, 0]
当gap = 5 时,经过第 4 轮插入排序后的结果: [5, 4, 3, 2, 6, 10, 9, 8, 7, 1, 0]
当gap = 5 时,经过第 5 轮插入排序后的结果: [5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 0]
当gap = 5 时,经过第 6 轮插入排序后的结果: [0, 4, 3, 2, 1, 5, 9, 8, 7, 6, 10]
当gap = 2 时,经过第 1 轮插入排序后的结果: [0, 4, 3, 2, 1, 5, 9, 8, 7, 6, 10]
当gap = 2 时,经过第 2 轮插入排序后的结果: [0, 10, 3, 4, 1, 5, 9, 8, 7, 6, 2]
当gap = 2 时,经过第 3 轮插入排序后的结果: [0, 10, 1, 4, 3, 5, 9, 8, 7, 6, 2]
当gap = 2 时,经过第 4 轮插入排序后的结果: [0, 10, 1, 4, 3, 5, 9, 8, 7, 6, 2]
当gap = 2 时,经过第 5 轮插入排序后的结果: [0, 10, 1, 4, 3, 5, 9, 8, 7, 6, 2]
当gap = 2 时,经过第 6 轮插入排序后的结果: [0, 10, 1, 4, 3, 5, 9, 8, 7, 6, 2]
当gap = 2 时,经过第 7 轮插入排序后的结果: [0, 10, 1, 4, 3, 5, 7, 8, 9, 6, 2]
当gap = 2 时,经过第 8 轮插入排序后的结果: [0, 10, 1, 4, 3, 5, 7, 6, 9, 8, 2]
当gap = 2 时,经过第 9 轮插入排序后的结果: [0, 10, 1, 4, 2, 5, 3, 6, 7, 8, 9]
当gap = 1 时,经过第 1 轮插入排序后的结果: [0, 10, 1, 4, 2, 5, 3, 6, 7, 8, 9]
当gap = 1 时,经过第 2 轮插入排序后的结果: [0, 1, 10, 4, 2, 5, 3, 6, 7, 8, 9]
当gap = 1 时,经过第 3 轮插入排序后的结果: [0, 1, 4, 10, 2, 5, 3, 6, 7, 8, 9]
当gap = 1 时,经过第 4 轮插入排序后的结果: [0, 1, 2, 4, 10, 5, 3, 6, 7, 8, 9]
当gap = 1 时,经过第 5 轮插入排序后的结果: [0, 1, 2, 4, 5, 10, 3, 6, 7, 8, 9]
当gap = 1 时,经过第 6 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 10, 6, 7, 8, 9]
当gap = 1 时,经过第 7 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 10, 7, 8, 9]
当gap = 1 时,经过第 8 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 10, 8, 9]
当gap = 1 时,经过第 9 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 9]
当gap = 1 时,经过第 10 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
共经过 44 次交换或赋值操作
当最好的情况下
def shell_sort(datas):
count=0
gap=len(datas)//2
while gap>0:
index=0
for i in range(gap,len(datas)):
index+=1
temp=datas[i]
for j in range(i,0,-gap):
if temp<datas[j-gap]:
datas[j],datas[j-gap]=datas[j-gap],datas[j]
count+=1
else:
if j!=i:
datas[j]=temp
count+=1
break
print(f"当gap = {gap} 时,经过第 {index} 轮插入排序后的结果:",datas)
gap//=2
print(f"共经过 {count} 次交换或赋值操作")
return datas
if __name__=="__main__":
datas=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
datas=shell_sort(datas)
执行结果如下:注意,下面虽然打印了很多,但是交换或者赋值运算却未执行一次,即执行效率非常高
当gap = 5 时,经过第 1 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 5 时,经过第 2 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 5 时,经过第 3 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 5 时,经过第 4 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 5 时,经过第 5 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 5 时,经过第 6 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 1 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 2 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 3 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 4 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 5 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 6 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 7 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 8 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 2 时,经过第 9 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 1 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 2 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 3 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 4 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 5 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 6 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 7 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 8 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 9 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
当gap = 1 时,经过第 10 轮插入排序后的结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
共经过 0 次交换或赋值操作