python选择排序算法图解,快速排序算法python代码

  python选择排序算法图解,快速排序算法python代码

  排名算法是《数据结构与算法》中最基础的算法之一,也是面试中最常被考察的知识点。在本文中,我将详细介绍10种常见的内部排序算法,以及如何用Python实现它们。记得收藏,关注,喜欢。

  注意:代码、数据和技术交流的完整版本可在最后获得。

  排序算法可以分为内部排序和外部排序。内部排序是指数据记录在内存中排序,外部排序是指排序后的数据太大,无法一次性容纳所有排序后的记录,排序过程中需要访问外部存储。

  常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。

  用一张图总结一下:

  时间复杂度:

  平方顺序(O(n2))排序:各种简单排序、直接插入、直接选择、冒泡排序;线性对数序(O(nlog2n))排序:快速排序、堆排序、归并排序;Hill排序:O (n1))排序,其中(是0到1之间的常数;线性顺序(O(n))排序:基数排序,此外还有桶和箱排序。关于稳定性:

  排序后两个相等键值的顺序与排序前相同。稳定排序算法:冒泡排序、插入排序、合并排序和基数排序。不是一个稳定的排序算法:选择排序,快速排序,希尔排序和堆排序。名词解释:

  n:数据规模。k:“桶”的数量。就地:占用常量内存,不占用额外内存。错位:占用额外的内存。01冒泡排序

  冒泡排序也是一种简单直观的排序算法。它反复访问要排序的序列,一次比较两个元素,如果它们的顺序不对,就切换它们。访问序列的工作一直重复到不需要交换为止,也就是说序列已经排序了。这种算法的名字来源于较小的元素会通过交换慢慢“浮”到序列的顶端。

  冒泡排序作为一种最简单的排序算法,给我的感觉和单词书里的嫌弃的出现一样,每次都是第一页第一,所以我最熟悉。冒泡排序还有一个优化算法,就是设置一个标志。当元素在一个序列遍历中没有交换时,就证明这个序列是有序的。但是这种改进对提高性能并没有太大的作用。

  1.算法步骤比较相邻的元素。如果第一个比第二个大,两个都换。对每一对相邻的元素做同样的工作,从开始的第一对到结束的最后一对。在这一步之后,最后一个元素将是最大的数字。对除最后一个元素之外的所有元素重复上述步骤。每次对越来越少的元素重复上述步骤,直到没有要比较的数字对。2.动画演示

  3.Python代码

  def bubbleSort(数组):

  对于范围内的I(1,len(arr)):

  对于范围(0,len(arr)-i)中的j:

  if arr[j] arr[j 1]:

  数组[j],数组[j 1]=数组[j 1],数组[j]

  返回arr02选择排序

  排序是一种简单直观的排序算法。不管什么数据进去,都是O (n)的时间复杂度。所以在使用的时候,数据量越小越好。唯一的好处可能就是不占用额外的内存空间。

  1.算法步骤首先找到未排序序列中最小(最大)的元素,并将其存储在排序序列的开头。然后继续从剩余的未排序元素中寻找最小(最大)的元素,然后放在排序后的序列的末尾。重复第二步,直到所有元素都排序完毕。2.动画演示

  3.Python代码

  定义选择排序(arr):

  对于范围内的I(len(arr)-1):

  #记录最小数量的索引

  minIndex=i

  对于范围内的j(I ^ 1,len(arr)):

  if arr[j] arr[minIndex]:

  minIndex=j

  当# i不是最小数时,用最小数交换I。

  如果我!=minIndex:

  arr[i],arr[minIndex]=arr[minIndex],arr[i]

  Return arr03插入排序

  虽然插入排序的代码实现没有冒泡排序和选择性排序那么简单粗暴,但是它的原理应该是最容易理解的,因为玩过扑克的人应该都能秒懂。插入是最简单、最直观的排序算法。它的工作原理是在排序后的序列中从后向前扫描未排序的数据,找到对应的位置并插入。

  和冒泡排序一样,插入排序也有一个优化算法,叫做对半插入。

  1.该算法步骤将待排序的第一序列的第一个元素视为有序序列,并将第二个元素至最后一个元素视为未排序序列。从头到尾扫描无序序列,将每个扫描的元素插入有序序列的适当位置。(如果要插入的元素等于有序序列中的一个元素,则将要插入的元素插入到等于的元素之后。) 2.动画演示

  3.Python代码

  定义插入排序(arr):

  对于范围内的I(len(arr)):

  preIndex=i-1

  current=arr[i]

  preIndex=0且arr[preIndex] current:

  arr[preIndex 1]=arr[preIndex]

  preIndex-=1

  arr[preIndex 1]=当前

  返回arr04 hill排序

  Hill排序,也称为降序增量排序算法,是插入排序的一个更高效的改进版本。然而,希尔排序算法是不稳定的。

  希尔排序基于插入排序的以下两个属性:

  在对几乎排序的数据进行操作时,插入排序是高效的,即可以达到线性排序的效率;但是插入排序一般效率很低,因为插入排序一次只能移动一位数据。Hill排序的基本思路是:首先,将待排序的整个记录序列分成若干子序列进行直接插入排序。当整个序列中的记录都是“基本有序”时,直接插入所有记录并依次排序。

  1.算法步骤选择增量序列t1、t2,tk,其中ti tj,tk=1;根据增量序列的个数k,对序列进行k次排序;每次排序时,根据对应的增量ti,将待排序的列分成若干个长度为m的子序列,每个子表直接插入排序。当增量因子只有1时,整个序列被当作一个表,表的长度就是整个序列的长度。2.Python代码

  定义外壳排序(arr):

  导入数学

  差距=1

  while(gap len(arr)/3):

  差距=差距*3 1

  而间隙0:

  对于范围内的I(gap,len(arr)):

  临时=数组[i]

  j=i-gap

  当j=0且arr[j] temp:

  arr[j缺口]

  间隙

  arr[j gap]=温度

  gap=math.floor(gap/3)

  返回arr

  }05合并排序

  归并排序是一种基于归并操作的有效排序算法。这个算法是分而治之的典型应用。

  作为分治思想的典型算法应用,归并排序通过两种方法实现:

  自顶向下递归(所有递归方法都可以通过迭代重写,所以有第二种方法);自底向上迭代。与选择性排序一样,合并排序的性能不受输入数据的影响,但它比选择性排序好得多,因为它总是O(nlogn)的时间复杂度。代价是额外的存储空间。

  1.算法步骤申请一个空间,使其大小为两个排序后的序列之和,空间用于存储合并后的序列;设置两个指针,其初始位置分别为两个排序序列的初始位置;比较两个指针指向的元素,选择一个相对较小的元素放入归并空间,将指针移动到下一个位置;重复步骤3,直到指针到达序列的末尾;将另一个序列的所有剩余元素直接复制到合并序列的末尾。2.动画演示

  3.Python代码

  定义合并排序(arr):

  导入数学

  if(len(arr) 2):

  返回arr

  middle=math.floor(len(arr)/2)

  left,right=arr[0:middle],arr[middle:]

  返回merge(mergeSort(左),mergeSort(右))

  定义合并(左、右):

  结果=[]

  而左和右:

  如果left[0]=right[0]:

  result . append(left . pop(0));

  否则:

  result . append(right . pop(0));

  离开时:

  result . append(left . pop(0));

  右侧:

  result . append(right . pop(0));

  返回06快速排序

  快速排序是由Tony Hall开发的一种排序算法。平均来说,对N个项目进行排序需要 (nlogn)次比较。在最坏的情况下,需要进行 (N2)比较,但这种情况并不常见。事实上,快速排序通常比其他 (NLOGN)算法快得多,因为它的内循环可以在大多数架构中高效实现。

  快速排序使用分治策略将一个列表分成两个子列表。

  快速排序是分治思想在排序算法中的典型应用。本质上,快速排序应该看作是一种基于冒泡排序的递归分治法。

  快速排序这个名字简单粗暴,因为只要一听到这个名字,你就会知道它存在的意义,那就是快速高效!是处理大数据最快的排序算法之一。

  虽然最坏情况的时间复杂度达到O (n),但人是优秀的,在大多数情况下,比平均时间复杂度为O(n logn)的排序算法表现更好,但不知道为什么。还好我的强迫症又犯了。查了更多的资料,终于在《算法艺术与信息学竞赛》上找到了满意的答案:

  快速排序最差的情况是O (n),比如顺序数列的快速排序。但其共享的期望时间为O(nlogn),O(nlogn)标记中隐含的常数因子很小,远小于稳定复杂度等于O(nlogn)的归并排序。所以对于大部分弱序列的随机序列,快速排序总是比归并排序好。

  1.算法步骤从序列中挑出一个元素,称为“pivot”;对数列重新排序,所有小于参考值的元素放在参考值的前面,所有大于参考值的元素放在参考值的后面(相同的数字可以在两边)。在这个分区退出后,基准位于系列的中间。这称为分区操作;递归排序小于参考值的元素子系列和大于参考值的元素子系列。在递归的最底层,序列的大小是零或一,也就是一直排序下去。虽然它一直在递归,但这种算法总是会退出,因为在每次迭代中,它至少会将一个元素放到最后一个位置。

  2.动画演示

  3.Python代码

  def快速排序(arr,left=None,right=None):

  如果不是isinstance,left=0(left,(int,float))否则向左

  right=len(arr)-1 if not is instance(right,(int,float)) else right

  如果向左向右:

  partitionIndex=partition(arr,left,right)

  快速排序(数组,左,分区索引-1)

  快速排序(arr,partitionIndex 1,右)

  返回arrdef分区(arr,left,right):

  枢轴=向左

  索引=透视1

  i=指数

  而我=右:

  if arr[i] arr[pivot]:

  交换(arr,I,index)

  指数=1

  i=1

  交换(数组,透视,索引-1)

  回报指数-1

  def swap(arr,I,j):

  Arr[i],arr[j]=arr[j],arr[i]07堆排序

  堆排序是指利用堆的数据结构设计的一种排序算法。Heap是一种类似于完全二叉树的结构,同时满足heap的性质:即子节点的键值或索引总是小于(或大于)其父节点。堆排序可以说是利用堆的概念进行的一种选择性排序。有两种方法:

  Top heap:每个节点的值大于等于其子节点的值,用于堆排序算法中的升序;Top heap:每个节点的值小于或等于其子节点的值,用于堆排序算法中的降序。堆排序的平均时间复杂度为 (nlogn)。

  1.算法步骤创建一个堆H[0…n-1];交换反应器头部(最大)和反应器尾部;将堆的大小减少1,调用shift_down(0)以便将新数组顶部的数据调整到相应的位置;重复步骤2,直到堆栈的大小为1。2.动画演示

  3.Python代码

  def buildMaxHeap(arr):

  导入数学

  对于范围内的I(math . floor(len(arr)/2),-1,-1):

  heapify(arr,I)

  def heapify(arr,I):

  左=2*i 1

  右=2*i 2

  最大=i

  if left arrLen和arr[left]arr[large]:

  最大=左侧

  如果右arrLen和arr[右]arr[最大]:

  最大=右侧

  如果最大!=我:

  交换(arr,I,最大)

  heapify(arr,maximum)def swap(arr,I,j):

  arr[i],arr[j]=arr[j],arr[i]

  定义堆排序(arr):

  全球arrLen

  arrLen=len(arr)

  buildMaxHeap(arr)

  对于范围内的I(len(arr)-1,0,-1):

  swap(arr,0,I)

  arrLen -=1

  heapify(arr,0)

  返回arr08盘点排序

  计数排序的核心是将输入的数据值转换成键,存储在额外的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入数据必须是一定范围内的整数。

  1.动画演示

  2.Python代码

  def countingSort(arr,maxValue):

  bucketLen=maxValue 1

  bucket=[0]*bucketLen

  sortedIndex=0

  arrLen=len(arr)

  对于范围内的I(arr len):

  如果不是bucket[arr[i]]:

  bucket[arr[i]]=0

  bucket[arr[i]]=1

  对于范围内的j(bucket len):

  while桶[j] 0:

  arr[sortedIndex]=j

  sortedIndex=1

  桶[j]-=1

  Return arr09桶排序

  桶排序是计数排序的升级版本。它利用了函数的映射关系,高效的关键在于这个映射函数的确定。为了提高桶排序的效率,我们需要做两件事:

  当有足够的额外空间时,尽量增加桶数。的映射函数可以将输入的N个数据均匀分布到K个桶中。同时,为了对桶中的元素进行排序,选择一个性能比较排序算法是非常重要的。

  输入数据能平均分配到每个桶最快是什么时候?

  最慢的时间是什么时候?当输入数据被分配到相同的桶时。

  代码Python def bucket_sort:

  桶排序

  min_num=分钟

  最大数量=最大数量

  #水桶的大小

  bucket_range=(最大数量-最小数量)/长度

  #桶阵列

  count _ list=[[]for I in range(len(s)1)]

  #用数字填充桶数组

  对于s中的I:

  count _ list[int((I-min _ num)//bucket _ range)]。追加(一)

  透明玻璃()

  # Backfill,其中sorted是通过桶内排序直接调用的。

  对于count_list中的I:

  对于排序后的j(I):

  追加(j)

  if _ _ name _ _==_ _ main _ _:

  a=[3.2,6,8,4,2,6,7,3]

  bucket_sort(a)

  Print(a) # [2,3,3.2,4,6,6,7,8]10基数排序

  基数排序是一种非比较整数排序算法。它的原理是把整数按照位数切割成不同的数,然后按照每个位数进行比较。由于整数也可以用特定格式表示字符串(如姓名或日期)和浮点数,所以基数排序不仅可以用于整数。

  1.基数排序与计数排序与桶排序基数排序有两种方法:

  所有三种排序算法都利用了桶的概念,但是桶的用法有明显的不同:

  基数:根据键值的每一位分配桶;计数排序:每个桶只存储一个键值;桶排序:每个桶存储一定范围的值。2.动画演示

  3.Python代码

  定义半径排序(列表):

  I=0 #最初按位排序。

  N=1 #最小位数设置为1(包括0)

  Max_num=max(list) #获取排序数组中的最大值。

  而max_num 10**n: #得到的最大数是多少位?

  n=1

  当我在:

  Bucket={} #用字典构建Bucket

  对于范围(10)中的x:

  Bucket.setdefault(x,[]) #清空每个桶

  列表中的x:#对每个位进行排序。

  Radix=int((x/(10**i))% 10) #获取每个位的基数

  桶[基数]。append(x) #将对应于

  组被添加到阶段#对应基的桶中。

  j=0

  对于范围(10)中的k:

  if len(bucket[k])!=0: #如果桶不为空

  对于桶[k]中的y:#将每个元素放入桶中

  List[j]=y #并将它放回数组中

  j=1

  i=1

  返回列表

  技术交流欢迎转载,收藏,有所收获,喜欢,支持!数据和代码可以从我这里获得。

  目前已开通技术交流群,群友2000多人。最好的添加笔记的方法是:兴趣来源,这样才能找到志同道合的朋友。

  方式,微信搜索微信官方账号:Python学习与数据挖掘,后台回复:加群

  转载请联系作者授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: