当前位置: 首页 > 科技观察

使用Python实现十大经典排序算法

时间:2023-03-20 18:57:11 科技观察

10种经典排序算法包括冒泡排序、选择排序、快速排序、归并排序、堆排序、插入排序、希尔排序、计数排序、桶排序、基数排序等。当然,还有一些其他的排序算法,大家可以继续研究。01冒泡排序冒泡排序(BubbleSort)是一种比较简单的排序算法。它反复访问待排序的元素,依次比较相邻的两个元素,顺序不对就交换,直到不再需要交换元素,排序完成。注:上图中,数字代表数据序列的原始索引号。算法过程比较相邻的元素,如果前一个大于后一个,交换两个位置。对排序后的数组中的每一对相邻元素做同样的操作,直到全部完成,此时最后一个元素将是本轮排序中最大的数。对剩下的元素继续重复上述步骤,直到没有要比较的元素为止。冒泡排序每次都是找最大的元素,所以需要遍历n-1次(n为数据序列的长度)。算法特性什么时候最快(BestCases):输入数据已经是正序的时候。什么时候最慢(WorstCases):当输入数据顺序相反时。Python代码defbubble_sort(lst):n=len(lst)foriinrange(n):forjinrange(1,n-i):iflst[j-1]>lst[j]:lst[j-1],lst[j]=lst[j],lst[j-1]returnlst02选择排序selectionsortingprinciple选择排序(SelectionSort)的原理,每一轮从待排序的记录中选择最小的元素,存储在序列的开头,然后从剩余的未排序元素中找到最小的元素,然后将其放在已排序序列的末尾。以此类推,直到所有待排序的数据元素个数为零。获取按最小值排序的数据序列。也可以在每一轮中找到具有最大值的元素。这样的话,排序后的数组最终是从大到小排列的。选择排序每次都是选择最小(最大)的元素,所以需要遍历n-1次。Python代码defselection_sort(lst):foriinrange(len(lst)-1):min_index=iforjinrange(i+1,len(lst)):iflst[j]=baseline]returnquick_sort(left)+[baseline]+quick_sort(右)04合并排序算法合并排序(MergeSort)是一种基于合并操作的有效排序算法。该算法是分治法的一个非常典型的应用。合并排序将两个有序子序列合并成一个有序序列。算法流程中有两个主要步骤(拆分和合并)。第一步:拆分序列直到只有一个元素;第二步:拆分完成后,开始递归合并。思路:假设我们有一个未排序的序列,那么我们先使用split方法将这个序列拆分成已排序的子序列(直到剩下一个元素)。然后使用merge方法将有序的子序列合并成一个有序的序列。图解算法拆分对于数据序列[15,11,13,18,10],我们先从数据序列的中间位置开始拆分,中间位置设为第一次拆分,如下:sequentially对子序列进行拆分,拆分过程如下:在merge过程中,对于左右分区及其子区间,递归使用merge方法。从左边最小的子区间开始,对于每个区间,依次将最小的数据放在最左边,然后对右边的区间做同样的事情。完整的合并过程图如下:Python代码defmerge_sort(lst):defmerge(left,right):i=0j=0result=[]whileilst[largest_index]:largest_index=left_indexifright_indexlst[largest_index]:largest_index=right_indexiflargest_index!=i:lst[largest_index],lst[i]=lst[i],lst[largest_index]adjust_heap(lst,largest_index,size)defbuilt_heap(lst,size):foriinrange(len(lst)//2)[::-1]:adjust_heap(lst,i,size)size=len(lst)built_heap(lst,size)foriinrange(len(lst))[::-1]:lst[0],lst[i]=lst[i],lst[0]adjust_heap(lst,0,i)returnlst06插入排序插入排序(InsertionSort)是将一个待排序的数据按每一步的大小插入到已排序数据序列中的合适位置,直到全部插入完成。插入排序就像打扑克一样,每次将后面的牌插入到之前排序好的牌中。Python代码definsertion_sort(lst):foriinrange(len(lst)-1):cur_num,pre_index=lst[i+1],iwhilepre_index>=0andcur_num0:foriinrange(gap,n):forjinrange(i,gap-1,-gap):iflst[j]0:lst[i]=j+nums_minbucket[j]-=1i+=1returnlst09桶排序的基本思想简单来说,bucket排序(BucketSort)是将数据一个一个分组到桶中,对每个桶中的数据进行排序,然后合并桶,完成桶排序。该算法分为分桶、入桶、入桶排序、合并数据四个步骤。分桶过程这里详细介绍分桶过程。对于一个取值范围为10到49的数组,我们把桶的大小取为10(defaultBucketSize=10),那么第一个桶的范围就是10到20,第二个桶的数据范围就是20到30。而很快。最终,我们一共需要4个桶来放入数据。对于后面排序过程中的数据序列,桶大小初始设置为20(defaultBucketSize=20)。经过计算,总共需要4个桶来放数据。然后将原数组按照数值大小放入对应的桶中,完成数据分组。对于桶中的数据序列,可以采用冒泡排序、选择排序等多种排序算法对数据进行排序。这些算法在之前的视频中都有介绍,大家可以去了解一下。这里,我选择冒泡排序对桶中的数据进行排序。桶内排序完成后,按照桶内顺序合并数据,得到所有按数值排序的数据序列。Python代码defbucket_sort(lst,defaultBucketSize=4):maxVal,minVal=max(lst),min(lst)bucketSize=defaultBucketSizebucketCount=(maxVal-minVal)//bucketSize+1buckets=[[]foriinrange(bucketCount)]fornuminlst:buckets[(num-minVal)//bucketSize].append(num)lst.clear()forbucketinbuckets:bubble_sort(bucket)lst.extend(bucket)returnlst10radixsort基数排序(radixsort)属于“分布排序”(distributionsort),它是通过keyvalue的一部分信息,将要排序的元素分配到一定的“桶”中,达到排序的效果。基数排序适用于所有元素均为正整数的数组。基本思想是排序过程分为“分配”和“收集”。排序过程中,将元素分层为多个键进行排序(一般以值的个位、十位、百位、……来区分),多键排序是从最显性的键到最不重要的。键码的顺序或从最次要到最主要的键码依次排序。基数排序方法可以采用最低位优先级LSD(Leastsgnificantdigital)方法或最高位优先级MSD(Mostsgnificantdigital)方法。LSD的排序方式是从key值的最右边开始,而MSD正好相反,是从key值的最右边开始。从左边开始。LSD的基数排序适用于位数较少的数字。如果位数很多,使用MSD的效率会更好。MSD的方法与LSD刚好相反。相同的。算法流程这里以最低位优先LSD为例。首先,根据个位数的值,在扫描值时将它们分配到编号为0到9的桶中,然后将桶中的值串联起来。将这些桶中的值重新连接起来,组成一个新的序列,然后再进行一次分配,这次是按照十位数。如果排序对象的位数超过三位,则继续上述操作,直到最高位为止。Python代码#LSDRadixSortdefradix_sort(lst):mod=10div=1mostBit=len(str(max(lst)))buckets=[[]forrowinrange(mod)]whilemostBit:fornuminlst:桶[num//div%mod].append(num)i=0forbucketinbuckets:whilebucket:lst[i]=bucket.pop(0)i+=1div*=10mostBit-=1returnlst11总结以上就是使用Python实现10个经典排序算法的相关内容。对于这些排序算法的实现,代码并不是最重要的。了解各种算法的基本思想、基本原理和内部实现过程很重要。对于每个算法,也可以用其他编程语言来实现。而且,同一个算法,即使只使用Python语言,也有很多不同的代码方法可以实现,但基本原理是一样的。