- 冒泡排序
- 选择排序
- 直接插入排序
- 快速排序
- 堆排序
- 归并排序
- 希尔排序
- 总结
- 作业
一、冒泡排序
思路:n个数需要进行n-1趟排序,每一趟排序就是两个相邻的数组比较,交换位置。第i趟排序需要交换n-i-1次
代码:
#Author:Yueru Sun def bubble_sort(data): for i in range(0,len(data)-1): for j in range(0,len(data)-i-1): if data[j]>data[j+1]: data[j],data[j+1]=data[j+1],data[j] return data print(bubble_sort([1,3,4,21,10]))
###################################################
#时间复杂度o(n*n)
优化的代码:(最好的情况:针对原来排序的序列本来就是有序的,时间复杂的变为0(n))
就是如果出现某一趟排序未交换位置,那么就可以直接break不进行下一趟排序了
def bubble_sort(data): for i in range(0,len(data)-1): flag=False#表示未交换 for j in range(0,len(data)-i-1): if data[j]>data[j+1]: data[j], data[j + 1] = data[j + 1], data[j] flag=True if flag=='False': break return data print(bubble_sort([1,3,4,21,10]))
二、选择排序
原理:n个元素需要进行n-1趟排序,每一趟都会选出最小(大)的那个数组放到正确的位置,下一趟就遍历表中的剩下的元素,继续。。。
代码:
def select_sort(data): for i in range(0,len(data)-1): min_num=i#最小元素的下标,默认是每一趟的第一个数字 for j in range(i+1,len(data)):#每一趟需要在data[i+1]~data[len(data)-1]中找到最小(大)的那个数字的位置 if data[j]<data[min_num]: min_num=j#把最小元素的下标修改未j #for语句执行结束后就表示在这趟循环中找到了 在data[i+1]~data[len(data)-1]中找到最小(大)的那个数字 的位置 if min_num!=i:#如果最初假定的i不是 data[i],data[min_num]=data[min_num],data[i] return data print(select_sort([5,3,2,1,10]))
时间复杂度:o(n*n)
三、直接插入排序
原理:列表被分为有序区和无序区,默认最初的有序区是第一个元素。每次从无序区中选择一个元素,插入到有序区位空置,直到无序区变
代码:
def insert_sort(data): for i in range(0,len(data)): key=data[i] j=i-1#有序序列的最后一个元素 while j>=0:#当有序序列不为空 if data[j]>key: data[j+1]=data[j]#j之后的元素后移 data[j]=key#把key放到第j个位置 j=j-1#往前移动 return data
时间复杂度:o(n*n)
四、快速排序
原理:每一趟循环使得一个元素归位,同时列表被分成两部分,左边的都比归位元素小,右边的都比归位元素大
代码:
def quick_sort(data,left,right): if left<right: #分割成两部分 mid=partion(data,left,right) #递归实现 quick_sort(data,left,mid-1) quick_sort(data,mid,right) def partion(data,left,right): temp=data[left] while left<right: while left<right and temp<=data[right]: right-=1 data[left]=data[right] while left<right and temp>=data[left]: left-=1 data[right]=data[left] data[left]=temp#或者写data[right]=temp,因为此时left和right相遇了,相遇的位置就是temp存放的位置 return left
平均时间复杂度:o(n*logn)
最坏的情况:o(n*n)
五、堆排序
原理:
建立堆
得到堆顶元素,为最大元素
去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。
堆顶元素为第二大元素。
重复步骤3,直到堆变空。
可以参考:https://www.cnblogs.com/chengxiao/p/6129630.html
https://blog.csdn.net/sxhelijian/article/details/50295637
代码:
def heap_sort(data): n=len(data) for i in range(n//2-1,-1,-1):#建立堆,只需要调整堆中的父节点 sift(data,i,n-1) for i in range(n-1,-1,-1):#从堆的最后一个元素开始调整 data[0],data[i]=data[i],data[0] sift(data,0,i-1) def sift(data,low,high):#low是需要调整的堆的堆顶序号,high是需要调整的堆的最后一个元素的序号 i=low j=2*i+1 tmp=data[i] while j<=high: if j<=high and data[j]<data[j+1]: j+=1 if tmp<data[j]: data[i]=data[j] i=j j=2*i+1 else: break data[i]=tmp
时间复杂度:o(n*logn)
六、归并排序
原理:分治的思想。www.cnblogs.com/chengxiao/p/6194356.html
代码:
#归并 def merge(data,low,mid,high): i=low j=mid+1 ltmp=[] while i<mid and j<high: if data[i]<data[j]: ltmp.append(data[i]) i+=1 else: ltmp.append(data[j]) j+=1 while j<=mid: ltmp.append(data[i]) i+=1 while j<=high: ltmp.append(data[j]) j+=1 data[low:high+1]=ltmp def mergesort(data,low,high): if low<high: mid=(low+high)//2 mergesort(data,low,mid) mergesort(data,mid+1,high) merge(data,low,mid,high)
时间复杂度:O(nlogn)
空间复杂度:O(n)
七、希尔排序
原理:
希尔排序是一种分组插入排序算法。
首先取一个整数d1=n/2,将元素分为d1个组,每组相邻量元素之间距离为d1,在各组内进行直接插入排序;
取第二个整数d2=d1/2,重复上述分组排序过程,直到di=1,即所有元素在同一组内进行直接插入排序。
希尔排序的最后一趟就是直接插入排序
代码:
#希尔排序 def sheel_sort(data): gap=len(data)//2 while gap>0: for i in range(gap,len(data)): key=data[i] j=i-gap while j>=0: if key<data[j]: data[j+gap]=data[j] data[j + gap] = key j-=gap gap/=2
时间复杂度:时间复杂度: O((1+τ)n)