- 冒泡排序
- 选择排序
- 直接插入排序
- 快速排序
- 堆排序
- 归并排序
- 希尔排序
- 总结
- 作业
一、冒泡排序
思路:n个数需要进行n-1趟排序,每一趟排序就是两个相邻的数组比较,交换位置。第i趟排序需要交换n-i-1次
代码:
1 2 3 4 5 6 7 8 | #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 ]))<br> ###################################################<br>#时间复杂度o(n*n) |
优化的代码:(最好的情况:针对原来排序的序列本来就是有序的,时间复杂的变为0(n))
就是如果出现某一趟排序未交换位置,那么就可以直接break不进行下一趟排序了
1 2 3 4 5 6 7 8 9 10 11 | 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趟排序,每一趟都会选出最小(大)的那个数组放到正确的位置,下一趟就遍历表中的剩下的元素,继续。。。
代码:
1 2 3 4 5 6 7 8 9 10 11 | 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 ]))<br>时间复杂度:o(n * n) |
三、直接插入排序
原理:列表被分为有序区和无序区,默认最初的有序区是第一个元素。每次从无序区中选择一个元素,插入到有序区位空置,直到无序区变
代码:
1 2 3 4 5 6 7 8 9 10 | 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<br><br>时间复杂度:o(n * n) |
四、快速排序
原理:每一趟循环使得一个元素归位,同时列表被分成两部分,左边的都比归位元素小,右边的都比归位元素大
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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.youkuaiyun.com/sxhelijian/article/details/50295637
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #归并 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,即所有元素在同一组内进行直接插入排序。
希尔排序的最后一趟就是直接插入排序
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #希尔排序 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 <br>时间复杂度:时间复杂度: O(( 1 + τ)n) |
转自https://www.cnblogs.com/mesunyueru/p/8974734.html