分类算法摘要

时间:2025 07 01 10:52:25 来源:网络 浏览:0

大家好,今天来为大家分享分类算法摘要的一些知识点,和的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!

分类算法摘要

0X00、简介

1。排序的定义:输入:n数字A1,A2,…,输出的序列:序列A1,A2',A2',…,AN',AN',A1’=A2’=A2’=…=AN’2。排序算法排序算法的复杂性概述

时间复杂性

最好的情况

最坏的情况

空间复杂性

排序方式

稳定

气泡排序

o(n^2)

在)

o(n^2)

o(1)

就地

稳定

选择排序

o(n^2)

o(n^2)

o(n^2)

o(1)

就地

不稳定

插入排序

o(n^2)

在)

o(n^2)

o(1)

就地

稳定

希尔排序

o(nlogn)

o(nlog2n)

o(nlog2n)

o(1)

就地

不稳定

合并排序

o(nlogn)

o(nlogn)

o(nlogn)

在)

外面

稳定

快速排序

o(nlogn)

o(nlogn)

o(n^2)

o(logn)

分类算法摘要

就地

不稳定

堆排序

o(nlogn)

o(nlogn)

o(nlogn)

o(1)

就地

不稳定

计数排序

o(n+k)

o(n+k)

o(n+k)

好的)

外面

稳定

水桶排序

o(n+k)

o(n+k)

o(n^2)

o(n+k)

外面

稳定

基数排序

o(n * k)

o(n * k)

o(n * k)

o(n+k)

外面

稳定

3。术语解释稳定性:如果a=b,并且a在b之前,则a在排序后仍在b之前,则算法据说是稳定的;否则它是不稳定的。内部排序:所有排序操作都在内存中完成;外排序:由于数据太大,因此数据放在磁盘上,并且只能通过磁盘和内存的数据传输来执行排序;时间复杂性:算法执行所需的时间。空间复杂性:运行程序所需的内存大小。 4。关于时间复杂性的排序:(o(n^2))排序:各种简单类型:直接插入,直接选择和气泡排序; (O(nlog2n))排序:快速排序,堆排序和合并排序; o(n1+))排序,是0到1之间的常数:山等级(o(n))排序:基数排序,存储桶,框排序。 5。关于稳定性的分类:稳定分类算法:气泡分类,插入分类,合并排序和基本排序不是稳定的排序算法:选择排序,快速分类,山丘分类,堆分类

0X01、冒泡排序

泡泡分类是一种且效率低的分类算法,但效率低下的algorang及其相互交换且相互交换。

1. 算法描述

语言描述

1。比较相邻元素。如果第一个比第二个大,则交换两个。 2。从第一对开始到最后一对的末尾,为每对相邻元素做相同的工作,以便最后一个元素应该是最大的数字; 3。重复除最后一个元素以外的所有元素的上述步骤; 4。重复步骤13,直到分类完成。伪代码描述

如果a [j] a [j] [j-1] 4交换A [J-1]

2. 复杂度

时复杂性,则i=1至a.length-j=a=a的气泡- sort(a)1,j=a=a。

最佳情况:t(n)=o(n)最坏情况:t(n)=o(n^2)平均情况:t(n)=o(n^2)空间复杂性:o(1)

3. 代码实现如下

def bubble_sort(A:列表): cnt=len(a)如果不是CNT3:返回I范围内的I(1,CNT): j in范围(I-1,CNT-1): IF A [J+1] A [J+1] : A [J+1] a [j]for i在范围内(cnt-2):for j for J中的j(cnt-1,i,-1):如果a [J] 47、34、5、23] Bubble_sort(a)打印(a)

0X02、插入排序

插入插入是一种简单有效的排序方法。总体想法是比较要分类的元素旁边已经排序的元素。如果它大于此元素,则将元素移至前后一步,直到找到小于要排序元素的值并将其插入其后面。然后对要排序的下一个元素进行排序。

1. 算法思路

语言描述

1。从第一个元素开始,可以将元素视为已排序; 2。取出下一个元素,然后在已经排序的元素序列中向后扫描; 3。如果元素(排序)大于新元素,请将元素移至下一个位置; 4。重复步骤3,直到找到位置小于或等于新元素的位置的位置; 5。在该位置插入新元素之后; 6。重复步骤25。伪代码描述

插入- 插入(a):1用于j=2至a.length:2 key=a [j] 3 i=j -14时,i 0和a [i] key3:5 a [i+1]=a [i+1]=a [i] 6 i=i=i -17 a [i+1]

最佳情况:t(n)=o(n)。最坏的情况:t(n)=o(n^2)。平均情况:t(n)=o(n^2)。空间复杂性

o(1)。因为它占用存储空间来放置密钥。

2. 算法复杂度

DEF INSERT_SORT(A:列表): CNT=LEN(a)如果不是CNT 3:返回i范围内的i返回A(cnt -1):值=a [i + 1] pre_index-=1 a [pre_index+1]=值返回aif __name __=='___________________________ O(n2),因此,当您使用它时,数据大小越小。唯一的好处是它不占用额外的内存空间。从理论上讲,选择排序也可能是普通人想到的最常见的分类方法。 Selection-Sort是一种简单而直观的排序算法。其工作原理:首先在未分类序列中找到最小的(大)元素,将其存储在排序序列的启动位置,然后继续从其余的未分类元素中查找最小的(大)元素,然后将其放在排序序列的末端。依此类推,直到分类所有元素为止。

3. 算法实现

分类算法摘要

1。初始状态:无序面积为r [1.n],订购面积为空; 2。在第i-thing阶的开头(i=1,2,3…n-1),当前的订购面积和无序区域分别为r [1.i-1]和r(i.n)。此行程排序从当前的无序区域中选择- 具有最小关键字的记录r [k]与无序区域的第一个记录R交换,因此R [1.I]和R [I+1.n)被更改为新的订购区域,并增加了记录数量的增加,并减少了记录次数的新订购区域; 3。N-1行程结束,阵列被排序。

0X03、选择排序

最佳情况:t(n)=o(n2)最坏情况:t(n)=o(n2)平均情况:t(n)=o(n2)

1. 算法分析

def selection_sort(a:列表):''''''' minIndex=i for j在范围(cnt)[i:] :如果a [j] a [minIndex] : a [minindex],a [j]=a [j],a [minindex]返回aif __name __========selection_sort(a)打印(a)

2. 算法复杂度

山丘排序是唐纳德·壳(Donald Shell)在1959年提出的一种分类算法。HillSorts也是一种插入物,这是改进后更有效的简单插入分类版本,也被称为逐步分类,也称为AlgorithM,是第一个AlgorithM的缩小(通过AlgorithM),是通过o的第一个Algorith(n2)(N2)。使其与插入排序不同的原因是,它优先考虑更远的元素。山丘分类也称为缩小的增量分类。 HILL分类是在下表中的某些增量中分组记录,并使用直接插入排序算法对每个组进行分类;随着增量逐渐减少,每个组都包含越来越多的关键字。当增量减少到1时,整个文件被分为一个组,算法终止。

3. 算法实现

让我们看一下山丘分类的基本步骤。在这里,我们选择增量差距=长度/2,然后减少增量并继续使用gap=gap/2。这种增量选择可以用{N/2,(N/2)/2…1}的序列表示,这称为增量序列。山上排序的增量序列的选择和证明是一个数学问题。我们选择的增量序列是相对常用的,也是山的增量,称为山丘增量,但实际上,这种增量序列不是最佳的。在这里,我们使用Hill增量进行示例。首先,将整个记录序列分为几个以直接插入和分类为子序列。特定算法描述:

选择一个增量序列T1,T2,…,TK,其中TITJ,TK=1;用k中的k中的序列在增量序列编号K中进行排序;对于每个顺序,根据相应的增量Ti将序列分为长度m的几个子序列,然后直接插入和分类每个子表。当增量因子仅为1时,整个序列被作为表处理,表格是整个序列的长度。

0X04、希尔排序

最佳情况:t(n)=o(nlog2 n)最坏情况:t(n)=o(nlog2 n)平均情况:t(n)=o(nlog2n)

1. 算法思路

def shell_sort(a:列表)最差的:o(n^2)空间复杂性:o(1)''''cnt=len(a)如果不是cnt:返回gap=cnt //2,而gap 0:则在范围内(gap,cnt,cnt,1): tmp=a [i] pre_index=a [i] pre_index=i] a [pre_index+gap]=a [pre_index] pre_index-=gap a [pre_index+gap]=tmp Gap //=2返回aif __name__=='__ main _________________________________合并分类是分裂和治理思想的实施。分区和治理模式的每一层都有三个步骤:

原始问题分解为几个子问题,这是原始问题的示例,规模较小。解决这些子问题,并递归解决每个子问题。但是,如果小问题的规模足够小,则可以直接解决。将这些子问题的解决方案合并为原始问题的解决方案。这是分裂和治理模型的想法。将大问题分为几个较小的子问题,然后将子问题分为几个较小的问题,直到可以直接解决。然后将所有子问题的解决方案合并为原始问题的解决方案。

2. 算法复杂度

合并分类完全是分裂和治理思想的实现。

语言描述

分解。要排序的N元素的序列分为两个子序列,每个子序列分别为N/2个元素。解决。递归使用合并排序对两个子序列进行分类。合并。合并两个分类子序列以产生分类的答案。伪代码描述

合并(a,p,q,r)1 n1=p -q+12 n2=r -q3令l [1.n1+1]和r [1.n2+1]为i=1至1至n15 l [i]=a [p+i -1] 6 for J=1=1=1至n27 r [q+j+j+j+j] 8 l [n l [n l [n l [n l [n l [q+j]=n l [n l [q+j] 8 l [n l [n l [q+j]=n l [n l [q+j]=n l [n l [n l [n l [q]=1] 111 j=112对于k=p至r13,如果l [i]=r [j] 14 a [k]=l [i] 15 i=i=i+116 e+116 e+116 a [k]=r [j] 18 j=j+1merge-sort(a,p,p,r)1如果p r2 q=(p r2 q=(p+r)/23 merge-sort(p+r)/23 merge-sort(p+r)/23 merge-sort(a,p,p,p,p,q)4 mer q+++1,q+++++++++++++++++++++sor合并(a,p,q,r)

3. 算法实现

时间复杂性

最佳情况:t(n)=o(n)最坏情况:t(n)=o(nlogn)平均情况:t(n)=o(nlogn)空间复杂性

o(1)

0X05、归并排序

def merge_sort(a:列表): cnt=len(a)如果cnt 2:返回a mid=cnt=cnt //2返回merge(merge_sort(merge_sort(a [:mid])列表):结果=[] i=0 j=0,而我(左)和j len(右):如果左[i]=右[j] : result.append.append(左[i])i +=1 els: i +=1 els:结果。 '__MAIN __': a=[2,1,4,6,6,3,45,76,76,47,34,5,23]打印(Merge_sort(a))

1. 算法思想

这些记录被分类为两个独立零件,通过一个顺序分为两个独立零件,并且某些记录的某些记录比其他部分小。然后,可以继续分别对这两个记录进行分类,以达到整个序列的顺序。

2. 算法复杂度

快速分类使用分隔方法将字符串分为两个子名单。特定算法描述如下:

语言描述

从序列中选择一个元素,称为“枢轴”并重新排序序列。所有具有比参考值较小的元素都放在参考的前面,并且所有具有较大元素的元素都放在参考值后面(相同的数字可以在任何一侧)。该分区退出后,参考位于序列的中间。这称为分区操作;递归分类的子序列小于参考元素和子序列,而不是参考元素。伪代码描述

QuickSort(A,P,R)1如果P R2 Q=分区(A,P,R)3 QuickSort(A,P,Q,Q-1)4 QuickSort(A,Q+1,R)分区(A,A,P,P,R)1 X=A [R] 2 I=P-13 for J=P到R-14 if r-14 if r-14 if A [J]=a [J]=x5 I=i=i=i=i=i+16 a [j i=i+16]返回i+1

3. 算法实现

时间复杂性

最佳情况:t(n)=o(nlogn)最坏情况:t(n)=o(n2)平均情况:t(n)=o(nlogn)空间复杂性

o(1)

0X06、快速排序

def quick_sort(array,l,r):如果l r: q=partition(array,l,l,r)quick_sort(arew_sort(array,l,l,q)quick_sort(arking_sort(array,q + 1,q + 1,r)def partition(array,l,l,l,l,l,r)3: i=l -1 fongand(if)3333330 if -1 forsj 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33(l -1)=array[r]: i +=1 array[i], array[j]=array[j], array[i] array[i+1], array[r]=array[r], array[i+1] return idef quicksort(arr): if len(arr)=1: return arr pivot=arr[len(arr) //2] left=[x for x in arr if x pivot]中间=[x for x in arr in arr如果x==pivot] right=[x for x in arr in arr if x pivot]返回QuickSort(左) +中间+ QuickSort(右)print(quicksort([3,6,6,8,10,1,2,1]))如果__ -name===34、5、23] Quick_Sort(a,0,len(a)-1)打印(a)

1. 算法思路

计数排序的核心是将输入数据值转换为键并将它们存储在附加的开放式阵列空间中。作为一种线性时间复杂性,计数排序要求输入数据必须是具有一定范围的整数。计数排序是一种稳定的排序算法。计数排序使用额外的数组C,其中i-the元素是要排序的数组a中值等于i的元素的数量。然后,根据数组C,A中的元素被排列到正确的位置。它只能对整数进行排序。

2. 算法复杂度

找到要分类的阵列中最大和最小的元素;计算每个元素中的i元素中的i次数在数组中出现,并将其存储在数组C的第i-then任期中;累积所有计数(从C中的第一个元素开始,将每个项目添加到上一个项目中);反向填充目标数组:将每个元素i放在新数组的C(i)中,然后为每个元素减去1个。

3. 算法实现

当输入元素是0到K之间的N整数时,其运行时间为O(N + K)。计数排序不是比较排序,并且排序速度比任何比较排序算法要快。由于用于计数的数组C的长度取决于要排序的数组中的数据范围(等于要排序的数组的最大值和最小值之间的差异1),这使得计数排序需要大量的时间和具有较大数据范围的数组的内存。

最佳情况:t(n)=o(n+k)最坏情况:t(n)=o(n+k)平均情况:t(n)=o(n+k)

0X07、计数排序

def count_sort_sort_sort_sort(array):长度=len(array)c=[array)c=[] c=[] res=[]在范围内(0,100): C.Append(0): C.Append(0): C.Append(0)in : C.Append(0) c [array [i]]=c [array [i]]+1 res.append(0)在范围内(0,100): c [i]=c [i-1]+c [i] for range In range(leng-1,-1,-1,-1): res [reng-1,-1): res [c [c [i] - 1] - 1] -1] - 1]=array [are] __name __=='__ main __': a=[2,1,4,6,6,3,45,76,47,34,5,23] print(Count_sort(a))

1. 算法思路

心脏固定性排序也是一种非相机分类算法。每个位都是从最低位排序的,具有O(kn)的复杂性,即阵列的长度,k是阵列中数字的数字数量最多;基数排序首先由最低位排序,然后收集;然后按最高位排序,依此类推,直到最高位为止。有时,某些属性具有优先顺序,首先以低优先级进行排序,然后以高优先级进行排序。最终顺序是高优先级是具有相同优先级的优先级,而优先级低的是具有相同优先级的优先级。基数排序基于分类并分别收集,因此稳定。

2. 算法复杂度

获取数组中的最大数字并获得位数; ARR是原始数组,每个位均从最低位取以形成一个radix数组。计数和排序radix(使用适用于小范围数的计数排序的特征)

3. 算法实现

最佳情况:t(n)=o(n * k)最坏情况:t(n)=o(n * k)平均情况:t(n)=o(n * k)有两种用于分类卡线性的方法:

从低位LSD排序的MSD排序来自低位基数排序与计数排序与存储桶排序所有三种排序算法都利用了桶的概念,但是如何使用桶有明显的差异:

基数排序:根据密钥值排序的每个数字分配计数计数:每个存储桶仅存储一个单个键值存储桶排序:每个存储桶存储一定范围的值

0X08、基数排序

def radix_sort(列表,列表,

radix=10): k = int(math.ceil(math.log(max(lists), radix))) bucket = [[] for i in range(radix)] for i in range(1, k+1): for j in lists: bucket[j//(radix**(i-1)) % (radix**i)].append(j) del lists[:] for z in bucket: lists += z del z[:] return listsif __name__ == '__main__': a = [2, 1, 4, 6, 3, 45, 76, 47, 34, 5, 23] radix_sort(a) print(a)

0X09、桶排序

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort) 的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排

1. 算法思路

人为设置一个 BucketSize,作为每个桶所能放置多少个不同数值(例如当 BucketSize==5 时,该桶可以存放{1,2,3,4,5}这几种数字,但是容量不限,即可以存放 100 个 3);遍历输入数据,并且把数据一个一个放到对应的桶里去;对每个不是空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序;从不是空的桶里把排好序的数据拼接起来。注意,如果递归使用桶排序为各个桶排序,则当桶数量为 1 时要手动减小 BucketSize 增加下一循环桶的数量,否则会陷入死循环,导致内存溢出。

2. 算法复杂度

桶排序最好情况下使用线性时间 O (n),桶排序的时间复杂度,取决于对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为 O (n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。 最佳情况:T (n) = O (n+k)最差情况:T (n) = O (n+k)平均情况:T (n) = O (n2) 

3. 算法实现

class node: def __init__(self, k): self.key = k self.next = Nonedef bucket_sort(lista): h = [] for i in range(0, 10): h.append(node(0)) for i in range(0, len(lista)): tmp = node(lista[i]) map = lista[i]//10 p = h[map] if p.key is 0: h[map].next = tmp h[map].key = h[map].key+1 else: while(p.next != None and p.next.key <= tmp.key): p = p.next tmp.next = p.next p.next = tmp h[map].key = h[map].key+1 k = 0 for i in range(0, 10): q = h[i].next while(q != None): lista[k] = q.key k = k+1 q = q.nextif __name__ == '__main__': a = [2, 1, 4, 6, 3, 45, 76, 47, 34, 5, 23] bucket_sort(a) print(a)

0X10、堆排序

堆排序 (heap-sort), 和归并排序一样,不同于插入排序的是,堆排序的时间复杂度是 O (nlogn)。与插入排序相同,不同于堆排序的是,堆排序具有空间原址性:任何时候都需要常数个额外的元素空间来存储临时数据。其思想便是引用一种成为堆的数据结构。常见的有大根堆(最大堆)和小根堆(最小堆)。在排序中一般使用大根堆,小根堆通常构建优先队列。 大根堆:除了根以外的所有节点 i 都满足:A [PARENT (i)]>=A [i]小根堆:除了根以外的所有节点 i 都满足:A [PARENT (i)]<=A [i]

1. 算法思路

伪代码描述 # 用于维护最大根堆的性质# 对于树高为h的大根堆,其时间复杂度为O(h)MAX-HEAPIFY(A,i)1 l = LEFT(i)2 r = RIGHT(i)3 if l <= A.heap-size and A[l] > A[i]4 largest = l5 else larget = r6 if r <= A.heap-size and A[r] > A[largest]7 largest = r8 if largest != i9 exchange A[i] with A[largest]10 MAX-HEAPIFY(A,largest)# 建堆BUILD-MAX-HEAP(A)1 A.heap-size = A.length2 for i = ⌊A.length/2⌋ downto 13 MAX-HEAPIFY(A, i)# 堆排序HEAP-SORT(A)1 BUILD-MAX-HEAP(A)2 for i = A.length downto 23 exchange A[1] with A[i]4 MAX-HEAPIFY(A, 1)

2. 算法复杂度

时间复杂度

用户评论

夜晟洛

终于整理了一份排序算法的对比表做出来!对这方面很感兴趣的朋友可以直接看表来理解不同算法的优缺点,比我以前写的一篇长文简单明了多了 haha.

    有20位网友表示赞同!

一笑抵千言

这个总结太棒了!我一直不太清楚各种排序算法的区别,看完之后发现原来还有这么多种方法!以后学*其他数据结构时会优先参考这篇文章。

    有9位网友表示赞同!

花开丶若相惜

这篇 "排序算法汇总" 文写的真详细啊!从基础的冒泡排序到复杂的分治法都有,而且还列出了每个算法的时间复杂度。收藏了!

    有18位网友表示赞同!

残留の笑颜

这个排序算法的排名不是很有说服力吧?我觉得插入排序在某些场景下效率还挺高的啊,至少比冒泡排序快得多。

    有16位网友表示赞同!

素颜倾城

我有个疑问:这篇总结中提到桶排序适用于离散的数据集,那连续的浮点数呢?有适合这类数据的排序算法吗?

    有15位网友表示赞同!

念旧情i

学*数据结构的时候真是太依赖这些总结了,每次都让我恍然大悟!希望以后能更新更多关于排序算法的内容,比如一些最新的研究成果。

    有15位网友表示赞同!

♂你那刺眼的温柔

对程序员来说,了解不同排序算法的特点非常重要啊,因为这关系到代码的效率!这篇 "排序算法汇总" 给我的启发很大,应该好好把各个算法原理都梳理一遍

    有9位网友表示赞同!

几妆痕

感觉这篇总结还有些不够全面,比如缺少一些基于堆的排序算法,也少了一些应用场景分析。

    有19位网友表示赞同!

权诈

对排序算法本身不是很感兴趣,主要就是想学*一下数据结构的思想。 不过这篇文章写得很详细很易懂,能够帮助我更好地理解这些算法背后的原理。

    有17位网友表示赞同!

不相忘

这篇总结比较适合初学者,如果你是高手的话可能已经非常了解了这些算法,这篇文可能无法给你带来新的启示。

    有6位网友表示赞同!

日久见人心

排序算法真是太复杂了!这篇文章的总结还是有点抽象,希望能加一些代码示例,这样才更好理解每个算法的操作过程。

    有6位网友表示赞同!

陌潇潇

感觉 "排序算法汇总" 写的不错,尤其喜欢他列出来的各种算法的时间复杂度。这个对我学*数据结构非常有帮助

    有15位网友表示赞同!

裸睡の鱼

对排序算法这种基础知识我早已经研究透了,这篇文章主要还是用来回顾一下不同算法的特性,方便以后快速复*。

    有16位网友表示赞同!

千城暮雪

我一直觉得快速排序是最好的排序算法,这篇 "排序算法汇总" 也确实这样介绍,不过我认为这个说法过于绝对,因为不同的场景下选择最佳算法还是需要考虑很多因素.

    有12位网友表示赞同!

灬一抹丶苍白

这篇文章总结的非常全面,涵盖了比较常见的排序算法,对于想要入门数据结构和算法的学生来说是个不错的资源。希望作者未来能继续更新更多内容!

    有13位网友表示赞同!

聽風

我发现这篇 "排序算法汇总" 对一些更高级的排序算法并没有详细介绍,比如基于图论的排序算法,这对于研究方向更偏向于算法效率的我来说可能有点遗憾。

    有12位网友表示赞同!

标题:分类算法摘要
链接:https://www.yaowan8090.com/news/xydt/46925.html
版权:文章转载自网络,如有侵权,请联系删除!
资讯推荐
更多
阴阳师4月22日更新内容:帝释天上线技能调整,红莲华冕活动来袭

阴阳师4月22日更新内容:帝释天上线技能调整,红莲华冕活动来袭[多图],阴阳师4月22日更新的内容有哪些?版本更新

2025-06-25
四川电视台经济频道如何培养孩子的学习习惯与方法直播在哪看?直播视频回放地址

四川电视台经济频道如何培养孩子的学习习惯与方法直播在哪看?直播视频回放地址[多图],2021四川电视台经济频

2025-06-25
湖北电视台生活频道如何培养孩子的学习兴趣直播回放在哪看?直播视频回放地址入口

湖北电视台生活频道如何培养孩子的学习兴趣直播回放在哪看?直播视频回放地址入口[多图],湖北电视台生活频道

2025-06-25
小森生活金币不够用怎么办?金币没了不够用解决方法

小森生活金币不够用怎么办?金币没了不够用解决方法[多图],小森生活金币突然就不够用的情况很多人都有,金币没

2025-06-25