python排序
排序
1.冒泡排序
冒泡排序(Bubble sort):时间复杂度O(n^2)
交换排序的一种。其核心思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序记录为止。
def bubbleSort(list): ''' 冒泡排序 :param list: :return: ''' for i in range(len(list)): for j in range(i,len(list)): if list[i] > list[j]: list[i],list[j]=list[j],list[i] return list
2.简单选择排序
简单选择排序(simple selection sort):时间复杂度O(n^2)
通过n-i次关键字之间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录进行交换。
通俗的说就是,对尚未完成排序的所有元素,从头到尾比一遍,记录下最小的那个元素的下标,也就是该元素的位置。再把该元素交换到当前遍历的最前面。其效率之处在于,每一轮中比较了很多次,但只交换一次。因此虽然它的时间复杂度也是O(n^2),但比冒泡算法还是要好一点。
def selectSort(list): ''' 选择排序:选择第一个数作为基准,其他数跟它比较,比它小则交换 与冒泡排序区别是,比较次数一样,但是每个数最多只交换一次 :param list: :return: ''' for i in range(len(list)): minnum=i #设置需要比较的数作为基准 for j in range(i+1,len(list)): if list[minnum] > list[j]: minnum=j #minnum取最小的值 if i != minnum: list[i], list[minnum] = list[minnum], list[i] return list
3.直接插入排序
直接插入排序(Straight Insertion Sort):时间复杂度O(n^2)
基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。
def insertSort(list): ''' 将一个无序的列表分割成2部分,一个为第一个元素,另外为一个列表;这样2个列表第一个就是有序的; :param list: :return: ''' for i in range(1,len(list)): j=i-1 #设置当前值前一个元素的标识 if list[i] <list[j]: temp=list[i] list[i]=list[j] j-=1 while j>=0 and list[j]> temp: list[j+1]=list[j] j=j-1 list[j+1]=temp return list
将第一个元素(或者最后一个)做为一个有序列表,其他的为无序列表,无序列表依次插入到有序列表中;比如有序列表中有i个元素,那么无序列表的第一个元素就是i+1,下标就是i,先与有序列表的最后一个元素进行比较,如果比它大,则直接插在最后;如果比它小,那么先保存这个数值,将有序列表的最后一个元素下标右移一位,即temp=list[i],list[i]=list[i-1],下标自减1,然后继续比较,直到跟第一个元素比较后,如果比它小,则插入它前面。这样一个无序列表的第一个数值就插入成功;依次类推 。
4. 快速排序
快排的思想:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
def quickSort(list,start,end): ''' 快速排序:选取任意一个数作为基准,然后跟其他所有元素进行比较,比它小的放它前面,比它大的放它后面 第一个数作为基准数base,然后从后往前找,找到比基准数小的,则将该数给第一个数,然后从前往后找,找到比基准数大的,则将该数给前面交换的那个数,最后再将基准数给i :param list: :param start: :param end: :return: ''' if start<end: i,j=start,end base=list[i] #基准数 while i < j: while i< j and list[j] >=base: j=j-1 list[i] = list[j] while i<j and list[i] <= base: i=i+1 list[j]=list[i] list[i]=base quickSort(list,start,i - 1) quickSort(list,j+1,end) return list
选择起点和终点,然后取第一个数作为基准(如果取最后一个数作为基准,那么就先从前往后找),假设七点为start,终点为end,先从end开始往前面找,如果找到比基准数小的,那么将这个值给start(start的初始值已用基准base保存),然后start开始往后找,找到比基准数大的数
那么将这个值给end,然后继续找,知道start跟end碰面则停止(i=j),然后将基准值赋给它,这样基准值前面的都是比它小的,后面的都是比它大的,分割成了2部分;然后递归调用继续查找。
5.归并排序
首先归并排序使用了二分法,归根到底的思想还是分而治之。拿到一个长数组,将其不停的分为左边和右边两份,然后以此递归分下去。然后再将她们按照两个有序数组的样子合并起来。
同时对两个数组的第一个位置进行比大小,将小的放入一个空数组,然后被放入空数组的那个位置的指针往后 移一个,然后继续和另外一个数组的上一个位置进行比较,以此类推。到最后任何一个数组先出栈完,就将另外i一个数组里的所有元素追加到新数组后面。
由于递归拆分的时间复杂度是logN 然而,进行两个有序数组排序的方法复杂度是N该算法的时间复杂度是N*logN 所以是NlogN。
def merge(left,right): ''' 合并 :param a: :param b: :return: ''' result=[] while len(left)>0 and len(right)>0: if left[0]<right[0]: result.append(left.pop(0)) else: result.append(right.pop(0)) #循环完毕后,其中一侧没有数据了,需要将另一个数组添加到数组后面 #因为只有一侧有数据而且数据都是大的,所以先加left还是right没有关系 result+=left result+=right #最后返回列表 return result def merge_sort(list): ''' 归并排序 :param list: :return: ''' if len(list)<=1: return list #由于列表长度可能是奇数 middle=len(list)//2 left=merge_sort(list[:middle]) right=merge_sort(list[middle:]) return merge(left,right) if __name__=='__main__': list=[49,38,65,97,76,13,27,49] print(merge_sort(list))

浙公网安备 33010602011771号