排序算法 ||蟒蛇 ||数据结构和算法
排序算法
1. 冒泡排序
在此,我们将较高的元素与其相邻的元素交换,直到到达数组的末尾。现在最高的元素位于最后一个位置。因此,我们更改边界并将其比上一个减少 1。最坏的情况下,我们必须迭代 n 次才能对数组进行排序。
def bubble_sort(arr): n = len(arr) for i in range(n): swapped = False # Last i elements are already in place, so we don't need to check them for j in range(0, n-i-1): # Swap if the element found is greater than the next element if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] # Swap the elements swapped = True if not swapped: break return arr
算法 -
- 迭代数组并找到最大元素,然后将其交换到最后一个。
- 比较所有相邻元素,如果较大的元素在较小的元素之前,则交换。继续这样做,直到到达数组的末尾。
- 维护一个标志:如果没有元素被交换,那么我们可以打破循环,因为数组已排序。
时间复杂度:
- 最佳情况 - 如果数组已经排序,则只需要一次迭代。时间复杂度 - O(n)
- 平均情况 - 如果数组是随机排序的,则时间复杂度 - O(n2)
- 最坏情况 - 如果数组按降序排列,那么我们将需要 n*2 次迭代。
空间复杂度 - O(1),不需要额外的内存。
优点 -
无需额外内存。
稳定,因为元素保持其相对顺序。
缺点 -
- 时间复杂度 - O(n2),对于大型数据集来说非常高。
应用-
- 仅当数据集非常小时才可以使用,并且由于时间复杂度较高,简单性胜过低效率。
2. 选择排序
在此,我们找到数组中最小的元素并将其替换为第一个元素。然后,我们将边界增加 1 并重复相同的步骤,直到到达数组的末尾。
def selectionSort(a): i = 0 while i<len(a): smallest = min(a[i:]) index_of_smallest = a.index(smallest) a[i],a[index_of_smallest] = a[index_of_smallest],a[i] i=i+1 return a
算法 -
迭代数组并找到最小元素。
与第一个元素交换位置,指针加1。
重复此过程,直到到达数组末尾。
时间复杂度:在所有三种情况下其时间复杂度均为 O(n2):最佳、平均和最差。这是因为我们必须选择最小元素并且每次都交换它,无论数组是否已经排序。
空间复杂度 - O(1),不需要额外的内存。
优点 -
无需额外内存。
比冒泡排序进行的交换更少。
缺点 -
时间复杂度 - O(n2),对于大型数据集来说非常高。
不稳定,因为它不保持相等元素的相对顺序。
应用程序 -
它可以在内存有限的系统中使用,因为它不需要额外的存储空间。
它用于最小化交换次数至关重要的系统,例如写入操作缓慢的系统。
3.插入排序
这是一种算法,通过从元素位置到数组开头迭代地向后检查,将未排序的元素插入到正确的位置。
def bubble_sort(arr): n = len(arr) for i in range(n): swapped = False # Last i elements are already in place, so we don't need to check them for j in range(0, n-i-1): # Swap if the element found is greater than the next element if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] # Swap the elements swapped = True if not swapped: break return arr
算法 -
从数组的第二个元素开始,与第一个元素进行比较。如果当前元素小于第一个元素,则交换它们。
现在增加指针并对第三个元素执行此操作:将其与第二个和第一个元素进行比较。
对其余元素重复相同的过程,将它们与之前的所有元素进行比较,并将它们插入到合适的位置。
时间复杂度:
- 最佳情况 - 如果数组已经排序,则只需要一次迭代。时间复杂度为 O(n)
- 平均情况 - 如果数组是随机排序的,那么时间复杂度是 O(n2)
- 最坏情况 - 如果数组按降序排列,那么我们将需要 n2 次迭代。
空间复杂度 - O(1),不需要额外的内存。
优点 -
- 不需要额外的内存。
- 稳定,因为元素保持其相对顺序。
缺点 -
时间复杂度 - O(n2),对于大型数据集来说非常高。
不稳定,因为它不保持相等元素的相对顺序。
应用-
- 对于实时数据流等元素实时到达且需要排序的场景非常高效。
4. 归并排序
归并排序是一种遵循分而治之方法的算法。它有两个主要步骤:首先,递归地划分数组,其次,按排序顺序合并划分后的数组。
def selectionSort(a): i = 0 while i<len(a): smallest = min(a[i:]) index_of_smallest = a.index(smallest) a[i],a[index_of_smallest] = a[index_of_smallest],a[i] i=i+1 return a
算法 -
通过计算中点将数组分成两半。
继续划分,直到每个子数组的长度为1。
在两半上调用合并函数:左半部分和右半部分。
使用三个指针进行合并过程:
- 左半数组的第一个指针。
- 右半数组的第二个指针。
- 已排序数组的第三个指针。
迭代两半并比较它们的元素。将较小的元素插入已排序的数组中,并将相应的指针加 1。
递归地重复此过程,直到整个数组排序完毕。
时间复杂度:归并排序在所有三种情况下的时间复杂度均为O(n log n):最佳、平均和最差。这是因为,无论数组是否已经排序,每次划分和合并都会遵循相同的步骤。
O( log n ) - 在除法阶段的每一步,数组大小减半。
O(n) - 在合并过程中,我们必须迭代所有元素一次。
所以总时间复杂度为 O (n) * O(log n) = O (n log n)
空间复杂度 - O(n),合并过程中需要额外的内存来存储临时数组。
优点 -
稳定,因为元素保持其相对顺序。
即使对于大型数据集,时间复杂度也是 O (n log n)。
适合并行处理,因为子数组是独立合并的。
缺点 -
- 时间复杂度 - O(n2),对于大型数据集来说非常高。
- 合并过程需要额外的内存。
- 未到位,因为需要额外的内存。
- 对于大多数数据集来说通常比快速排序慢。
应用程序 -
- 用于数据太大而无法放入内存的情况,例如合并大文件。
- 它用于对链表进行排序,因为不需要随机访问。
5. 快速排序
快速排序是一种遵循分而治之方法的算法。我们选择一个主元元素,并将主元放在正确的排序位置后,围绕主元元素对数组进行分区。
第一步是选择主元元素,然后围绕主元对数组进行分区。所有小于主元的元素都将位于左侧,所有大于主元的元素将位于其右侧。然后枢轴位于正确的排序位置。递归地,通过将数组分为两半来应用相同的过程:前半部分包含主元之前的元素,后半部分包含主元之后的元素。重复这个过程,直到每个子数组的长度达到1。
def bubble_sort(arr): n = len(arr) for i in range(n): swapped = False # Last i elements are already in place, so we don't need to check them for j in range(0, n-i-1): # Swap if the element found is greater than the next element if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] # Swap the elements swapped = True if not swapped: break return arr
算法 -
- 通过计算中点将数组分成两半。
- 选择一个枢轴;可以选择任何元素作为基准。
- 迭代数组并将每个元素与主元进行比较。
- 将所有小于主元的元素放置在左侧,将所有大于主元的元素放置在右侧。
- 将枢轴与左指针交换,使枢轴位于正确的排序位置。
- 递归地重复这个过程,直到分区的长度大于1。
时间复杂度:
1。最佳情况 - 时间复杂度 - O(n log n),当主元将数组分成相等的两半时。
2.平均情况 - 时间复杂度 - O(n log n),当主元将数组分成相等的两半时。但不一定相等。
3.最坏情况 - 时间复杂度 - O(n2) ,当 -
在已经排序的数组中选择最小的元素作为主元。
选择最大元素作为按降序排序的数组中的主元。
O( log n ) - 在除法阶段的每一步,数组大小减半。
O(n) - 在元素排序期间。
所以,总时间复杂度为 O(n) * O(log n) = O (n log n)
空间复杂度:
最佳和平均情况 - O(log n) - 用于递归堆栈。
最坏情况 - O(n) - 对于递归堆栈。
优点 -
- 对于大型数据集非常有效,除非枢轴选择不当。
- 它是缓存友好的,因为我们在同一个数组上进行排序,并且不将数据复制到任何辅助数组。
- 在不需要稳定性时,用于大数据的最快通用算法之一。
缺点 -
- 时间复杂度 - O(n2),对于大型数据集来说非常高。
- 不稳定,因为它不能维持相等元素的相对顺序。
应用程序 -
- 它用于编程库和框架。例如-Python的sorted()函数和Java的Array.sort()基于快速排序。
- 它通过在查询执行期间有效地对行进行排序来使用 indDatabase 查询优化。
- 由于其缓存友好的特性,它非常适合大型数据集的内存排序。
6.堆排序
堆排序是一种基于比较的排序算法。它是选择排序的扩展。在堆排序中,我们创建一个二叉堆并将最大或最小元素与最后一个元素交换。然后,我们将堆大小减少 1。重复此过程,直到堆的长度大于 1。
def bubble_sort(arr): n = len(arr) for i in range(n): swapped = False # Last i elements are already in place, so we don't need to check them for j in range(0, n-i-1): # Swap if the element found is greater than the next element if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] # Swap the elements swapped = True if not swapped: break return arr
算法 -
- 使用 heapify 进程构建最大堆。 Heapify 是一种用于维护二叉堆数据结构的堆属性的方法。
- 如果数组大小为 n,则包含 n//2 个父节点。
- 对于索引 i 处的父级:
a.它的左子节点位于索引 2i 1
b.它的右子节点位于索引 2i 2
- 迭代所有父级从索引 n//2 到 0 的子树,并对它们调用 heapify 函数。
- 现在,数组成为最大堆,最大元素位于索引 0。
- 将堆的第一个元素与最后一个元素交换,并将堆的大小减少 1。
- 重复这个过程,直到堆的长度大于1
时间复杂度:堆排序在所有三种情况下的时间复杂度均为 O(n log n):最佳、平均和最差。这是因为,无论数组是否已经排序,每次创建最大堆和交换元素时都会遵循相同的步骤。
O( log n ) - 创建最大堆
O(n) - 创建最大堆并且交换元素 n 次。
所以总时间复杂度为 O(n) * O(log n) = O(n log n)
空间复杂度:对于所有情况 - O(log n) - 对于递归堆栈。
优点 -
- 即使对于大型数据集,时间复杂度也是 O (n log n)。
- 内存使用率几乎恒定。
缺点 -
- 不稳定,因为它不能维持相等元素的相对顺序。
- 与合并排序相比,需要很多交换。
应用程序 -
- 对于实现频繁提取最大或最小元素的优先级队列非常有用。
- 在需要就地排序且内存使用至关重要的系统中很有用。
- 用于需要排名的场景。
7.计数排序和基数排序
计数排序是一种非基于比较的排序算法。当输入值的范围与要排序的元素的数量相比较小时,它特别有效。计数排序背后的基本思想是计算输入数组中每个不同元素的频率,并使用该信息将元素放置在正确的排序位置。
基数排序使用计数排序作为子例程。它将计数排序应用于数字的每个数字位并重复排序,直到处理完数组中最大数字的所有数字。
def bubble_sort(arr): n = len(arr) for i in range(n): swapped = False # Last i elements are already in place, so we don't need to check them for j in range(0, n-i-1): # Swap if the element found is greater than the next element if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] # Swap the elements swapped = True if not swapped: break return arr
def selectionSort(a): i = 0 while i<len(a): smallest = min(a[i:]) index_of_smallest = a.index(smallest) a[i],a[index_of_smallest] = a[index_of_smallest],a[i] i=i+1 return a
算法 -
查找数组中的最大数字并确定其中的位数 (d)。如果数字的长度为 d,则在数组上调用计数排序 d 次。
对数组中的每个数字位置调用计数排序,从个位开始,然后是十位,依此类推。
计数排序:
- 首先,创建一个索引数组,并根据元素的值映射元素。例如,如果数字为 4,则在索引数组的第 4 个索引处递增值。
- 从索引数组创建前缀和数组。
- 使用前缀和数组,创建一个等于输入数组长度的新排序数组
- 例如,如果前缀和数组在索引 1 处的值为 2,则将值 1 放置在排序数组中的位置 2 处,并将前缀和数组中的值递减 1
时间复杂度:
计数排序 的时间复杂度为 O(n k),其中 n 是要排序的元素数量,k 是值的范围(索引数组的大小)。此复杂度适用于所有三种情况:最佳、平均和最差。
这是因为,无论数组是否已经排序,每次都会遵循相同的步骤。
基数排序时间复杂度增加了 d 倍,其中 d 是数组中最大数字的位数。时间复杂度为 O(d * (n k))
所以总时间复杂度为 O (d) * O(n k) = O (d * (n k))
空间复杂度:对于所有情况 - O(n k),其中 n 是输入数组的长度,k 是索引数组中的值的范围。
优点 -
- 由于元素保持其相对顺序而稳定。
- 如果输入范围与输入数量相同,计数排序通常比所有基于比较的排序算法(例如合并排序和快速排序)执行得更快。
缺点 -
- 计数排序不适用于小数值。
- 如果要排序的值范围很大,计数排序效率很低。
- 非就地排序算法,因为它使用额外的空间 O(O(n m))。
应用程序 -
- 它用于计算字符串中字符出现次数等应用程序。
- 对于对具有大范围值的整数进行排序非常有用,例如 ID 或电话号码。
- 可以有效地对具有多个键的数据进行排序,例如日期或元组。
以上是排序算法 ||蟒蛇 ||数据结构和算法的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。 Python以简洁和强大的生态系统着称,C 则以高性能和底层控制能力闻名。

两小时内可以学到Python的基础知识。1.学习变量和数据类型,2.掌握控制结构如if语句和循环,3.了解函数的定义和使用。这些将帮助你开始编写简单的Python程序。

Python在游戏和GUI开发中表现出色。1)游戏开发使用Pygame,提供绘图、音频等功能,适合创建2D游戏。2)GUI开发可选择Tkinter或PyQt,Tkinter简单易用,PyQt功能丰富,适合专业开发。

2小时内可以学会Python的基本编程概念和技能。1.学习变量和数据类型,2.掌握控制流(条件语句和循环),3.理解函数的定义和使用,4.通过简单示例和代码片段快速上手Python编程。

Python在web开发、数据科学、机器学习、自动化和脚本编写等领域有广泛应用。1)在web开发中,Django和Flask框架简化了开发过程。2)数据科学和机器学习领域,NumPy、Pandas、Scikit-learn和TensorFlow库提供了强大支持。3)自动化和脚本编写方面,Python适用于自动化测试和系统管理等任务。

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

要在有限的时间内最大化学习Python的效率,可以使用Python的datetime、time和schedule模块。1.datetime模块用于记录和规划学习时间。2.time模块帮助设置学习和休息时间。3.schedule模块自动化安排每周学习任务。

Python在自动化、脚本编写和任务管理中表现出色。1)自动化:通过标准库如os、shutil实现文件备份。2)脚本编写:使用psutil库监控系统资源。3)任务管理:利用schedule库调度任务。Python的易用性和丰富库支持使其在这些领域中成为首选工具。
