概述
插入排序
一、直接插入
直接插入排序的特点:
- 空间复杂度为O(1)——需要一个位置来存储当前待排序元素
平均时间复杂度为O(n^2)——一轮可以确定一个元素位置,需N轮,若每轮都需进行N次,则需要n*n的时间 - 是一种稳定的排序算法,适用于链式、顺序存储——由该算法的实现过程中采取的方式决定
- 整个算法与数组初始状态无关
- 以从小到大排序为例,依次将元素Ki与Ki-1 Ki-2…K1比较,比较结果大于Ki的关键字后移一个位置,当Ki≥Kj时,Ki插入
- 在实现过程中从第二个元素往后依次开始,每个元素倒着和前面已经排好序的元素比较大小,决定是否插入到当前位置;若决定插入当前位置,则插入,否则继续往前和排好的元素比较
def InsertSort(input_list):
if len(input_list) == 0:
return []
sorted_list=input_list
for i in range(1,len(input_list)):
temp = sorted_list[i]
j = i - 1
while j >= 0 and temp < sorted_list[j]:
sorted_list[j + 1] = sorted_list[j]
j -= 1
sorted_list[j + 1] = temp
print(sorted_list)
return sorted_list
if __name__ == '__main__':
input_list = [20, 123,50,55,3,100,11,2,0]
print("input_list:")
print(input_list)
print("sorted_list:")
sorted_list=InsertSort(input_list)
print(sorted_list)
二、折半插入
- 折半插入和直接插入有相似之处,将直接插入的查找插入位置过程进行了优化
- 稳定的插入算法
- 大循环里有两个小循环,第一个循环从第二个元素开始往后依次和前面已有序的序列进行折半比较,找到合适的插入位置
第二个循环在找到合适的插入位置后进行有序序列的移动任务,然后插入元素,进行下一个大循环
#这里根据二分查找对查找插入位置的过程进行了优化,使查找速度更快
def BinaryInsertSort(input_list):
if len(input_list) == 0:
return []
result = input_list
for i in range(1, len(input_list)):
j = i - 1
temp = result[i]
# 第一个循环中二分查找合适位置的索引
insert_index = BinarySearch(result, i, result[i])
if insert_index != -1:
# 第二个循环,找到后将该位置及以后的元素向后移动
while j >= insert_index:
result[j + 1] = result[j]
j -= 1
# 将temp放入合适位置
result[j + 1] = temp
print("%dth" % i)
print(result)
return result
# 二分查找
def BinarySearch(input_list, end, value):
left = 0
right = end - 1
while left <= right:
middle = left + (right - left) // 2
if input_list[middle] >= value:
right = middle - 1
else:
left = middle + 1
return left if left < end else -1
if __name__ == '__main__':
input_list = [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
print("input_list:")
print(input_list)
sorted_list = BinaryInsertSort(input_list)
print("sorted_list:")
print(sorted_list)
三、希尔排序
- 对间隔为D1的几个子序列同时进行直接插入排序,同直插一致,在比较插入位置时进行元素后移,给要插入元素挪位置
- 缩小D,再次排序
- 一直到D=1,排序——结束
- 一轮排序会使每个子序列有序,算法不稳定
- 时间复杂度O(n^1.5)
- 需要一个增量序列来表示每次排序子序列的间隔D[t]
- 分为主函数和排序函数,主函数调用t次希尔排序函数完成功能
- 借用辅助位R0存放要插入位置的数据
def ShellSort(input_list):
length=len(input_list)
d=length // 2
if length == 0:
return []
sorted_list = input_list
n = 1
while d > 0:
for i in range(d,length):
j = i - d
temp = sorted_list[i]
while j >= 0 and temp < sorted_list[j]:
sorted_list[j+d] = sorted_list[j]
j -= d
sorted_list[j + d] = temp
d //= 2
print(sorted_list)
return sorted_list
if __name__ == '__main__':
input_list = [50,123,456,85,9,1,100,0,5]
sorted_list=ShellSort(input_list)
print(sorted_list)
交换排序
四、冒泡排序
冒泡排序的特点有:
- 空间复杂度为O(1)——在两数字交换位置时需要一个存储空间temp来完成交换功能
时间复杂度O(n^2)——最坏情况下每轮需比较所有未排序元素(在数据量很大时可抽象认为是n次),且每轮确定一个元素的位置,需n轮,一轮比较n次,n轮则比较n*n次 - 是一种稳定的排序算法
- 在算法中设置flag,flag为真时说明上一轮进行过交换,函数需要继续执行,为假时说明上一轮中为进行交换,整个列表已经有序,结束程序
def bubble_sort(nums):
for i in range(len(nums)-1):
flag=0
for j in range(len(nums)-i-1):
if nums[j]>nums[j+1]:
nums[j],nums[j+1]=nums[j+1],nums[j]
flag=1
if flag == 0:
return nums
return nums
def main():
li=[15,1,60,5,8,4,3]
print(li)
bubble_sort(li)
print(li)
main()
五、快速排序
- 快排可以实现一次交换消除多个逆序
- 从序列中选一个基准后,在两头设立指针(假设基准元素为Ri,指针为high low)
- high出现小于Ri则交换high和low指向元素的内容
low开始移动,出现大于Ri则交换至high所在位置,high重新开始移动 - 是对冒泡排序的一种改进
- 具体代码编写时分为主函数和一轮划分函数
主函数利用划分结果递归进行下一轮划分排序 - 划分函数主要完成的操作:借用一个辅助空间存基准
high出现小于r0的则交换至low
low开始移动,出现大于r0的则交换至high,high重新开始移动
最后返回low、high相同时的位置下标,下一轮移动从0~i-1 i+1~high
ef QuickSort(input_list, left, right):
def Divsion(input_list, left, right):
# pivot为基准
pivot = input_list[left]
while left < right:
while left < right and input_list[right] >= pivot:
right -= 1
# 找到一个元素小于基准元素,则把该元素放在前面
input_list[left] = input_list[right]
while left < right and input_list[left] <= pivot:
left += 1
# 找到一个元素大于基准元素,则把该元素放到后面
input_list[right] = input_list[left]
# 当left = right,即此时,left位置的左边都比基准元素小,
# left元素右边都比基准元素大,此时把基准元素放入该位置,
# 即该位置就是基准元素的最终排序位置
input_list[left] = pivot
return left
if left < right:
pivot_index = Divsion(input_list, left, right)
print("每执行本次分区后的结果:")
print(input_list)
# 用分治法对待排元素的左右两边分别递归进行QuickSort
QuickSort(input_list, left, pivot_index - 1)
QuickSort(input_list, pivot_index + 1, right)
if __name__ == '__main__':
input_list = [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
print("input_list:")
print(input_list)
QuickSort(input_list, 0, len(input_list) - 1)
print("sorted_list:")
print(input_list)
选择排序
六、简单选择排序
- 从未排序的序列中比较,选出最小的关键字
- 将最小的关键字与未排序序列的第一个交换,进行下一趟排序
- 要进行n-1趟,共比较O(n^2)移动O(n)
- 简单选择排序不稳定
- 算法中选择最小的过程与交换分开,先遍历选中最小元素,再进行交换,不借用r[0]
- 比较次数与初始状态无关
def SelectSort(input_list):
l = len(input_list)
if l == 0 :
return []
for i in range(l):
min_index = i
for j in range (i+1,l):
if input_list[min_index] > input_list[j]:
min_index = j
input_list[i],input_list[min_index]=input_list[min_index],input_list[i]
return input_list
if __name__ == '__main__':
input_list = [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
print("input_list:")
print(input_list)
sorted_list = SelectSort(input_list)
print("sorted_list:")
print(input_list)
最后
以上就是内向野狼为你收集整理的python实现数据结构中常用的几种排序算法的全部内容,希望文章能够帮你解决python实现数据结构中常用的几种排序算法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复