首页 后端开发 Python教程 排序算法 ||蟒蛇 ||数据结构和算法

排序算法 ||蟒蛇 ||数据结构和算法

Dec 18, 2024 am 09:08 AM

Sorting Algorithms || Python || Data Structures and Algorithms

排序算法

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
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

算法 -

  1. 迭代数组并找到最大元素,然后将其交换到最后一个。
  2. 比较所有相邻元素,如果较大的元素在较小的元素之前,则交换。继续这样做,直到到达数组的末尾。
  3. 维护一个标志:如果没有元素被交换,那么我们可以打破循环,因为数组已排序。

时间复杂度:

  • 最佳情况 - 如果数组已经排序,则只需要一次迭代。时间复杂度 - O(n)
  • 平均情况 - 如果数组是随机排序的,则时间复杂度 - O(n2)
  • 最坏情况 - 如果数组按降序排列,那么我们将需要 n*2 次迭代。

空间复杂度 - O(1),不需要额外的内存。

优点 -

  1. 无需额外内存。

  2. 稳定,因为元素保持其相对顺序。

缺点 -

  1. 时间复杂度 - O(n2),对于大型数据集来说非常高。

应用-

  1. 仅当数据集非常小时才可以使用,并且由于时间复杂度较高,简单性胜过低效率。

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. 迭代数组并找到最小元素。

  2. 与第一个元素交换位置,指针加1。

  3. 重复此过程,直到到达数组末尾。

时间复杂度:在所有三种情况下其时间复杂度均为 O(n2):最佳、平均和最差。这是因为我们必须选择最小元素并且每次都交换它,无论数组是否已经排序。

空间复杂度 - O(1),不需要额外的内存。

优点 -

  1. 无需额外内存。

  2. 比冒泡排序进行的交换更少。

缺点 -

  1. 时间复杂度 - O(n2),对于大型数据集来说非常高。

  2. 不稳定,因为它不保持相等元素的相对顺序。

应用程序 -

  1. 它可以在内存有限的系统中使用,因为它不需要额外的存储空间。

  2. 它用于最小化交换次数至关重要的系统,例如写入操作缓慢的系统。

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
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

算法 -

  1. 从数组的第二个元素开始,与第一个元素进行比较。如果当前元素小于第一个元素,则交换它们。

  2. 现在增加指针并对第三个元素执行此操作:将其与第二个和第一个元素进行比较。

  3. 对其余元素重复相同的过程,将它们与之前的所有元素进行比较,并将它们插入到合适的位置。

时间复杂度:

- 最佳情况 - 如果数组已经排序,则只需要一次迭代。时间复杂度为 O(n)
- 平均情况 - 如果数组是随机排序的,那么时间复杂度是 O(n2)
- 最坏情况 - 如果数组按降序排列,那么我们将需要 n2 次迭代。

空间复杂度 - O(1),不需要额外的内存。

优点 -

  1. 不需要额外的内存。
  2. 稳定,因为元素保持其相对顺序。

缺点 -

  1. 时间复杂度 - O(n2),对于大型数据集来说非常高。

  2. 不稳定,因为它不保持相等元素的相对顺序。

应用-

  1. 对于实时数据流等元素实时到达且需要排序的场景非常高效。

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. 通过计算中点将数组分成两半。

  2. 继续划分,直到每个子数组的长度为1。

  3. 在两半上调用合并函数:左半部分和右半部分。

  4. 使用三个指针进行合并过程:

  • 左半数组的第一个指针。
  • 右半数组的第二个指针。
  • 已排序数组的第三个指针。
  1. 迭代两半并比较它们的元素。将较小的元素插入已排序的数组中,并将相应的指针加 1。

  2. 递归地重复此过程,直到整个数组排序完毕。

时间复杂度:归并排序在所有三种情况下的时间复杂度均为O(n log n):最佳、平均和最差。这是因为,无论数组是否已经排序,每次划分和合并都会遵循相同的步骤。

O( log n ) - 在除法阶段的每一步,数组大小减半。

O(n) - 在合并过程中,我们必须迭代所有元素一次。

所以总时间复杂度为 O (n) * O(log n) = O (n log n)

空间复杂度 - O(n),合并过程中需要额外的内存来存储临时数组。

优点 -

  1. 稳定,因为元素保持其相对顺序。

  2. 即使对于大型数据集,时间复杂度也是 O (n log n)。

  3. 适合并行处理,因为子数组是独立合并的。

缺点 -

  1. 时间复杂度 - O(n2),对于大型数据集来说非常高。
  2. 合并过程需要额外的内存。
  3. 未到位,因为需要额外的内存。
  4. 对于大多数数据集来说通常比​​快速排序慢。

应用程序 -

  1. 用于数据太大而无法放入内存的情况,例如合并大文件。
  2. 它用于对链表进行排序,因为不需要随机访问。

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. 通过计算中点将数组分成两半。
  2. 选择一个枢轴;可以选择任何元素作为基准。
  3. 迭代数组并将每个元素与主元进行比较。
  4. 将所有小于主元的元素放置在左侧,将所有大于主元的元素放置在右侧。
  5. 将枢轴与左指针交换,使枢轴位于正确的排序位置。
  6. 递归地重复这个过程,直到分区的长度大于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)

空间复杂度:

  1. 最佳和平均情况 - O(log n) - 用于递归堆栈。

  2. 最坏情况 - O(n) - 对于递归堆栈。

优点 -

  1. 对于大型数据集非常有效,除非枢轴选择不当。
  2. 它是缓存友好的,因为我们在同一个数组上进行排序,并且不将数据复制到任何辅助数组。
  3. 在不需要稳定性时,用于大数据的最快通用算法之一。

缺点 -

  1. 时间复杂度 - O(n2),对于大型数据集来说非常高。
  2. 不稳定,因为它不能维持相等元素的相对顺序。

应用程序 -

  1. 它用于编程库和框架。例如-Python的sorted()函数和Java的Array.sort()基于快速排序。
  2. 它通过在查询执行期间有效地对行进行排序来使用 indDatabase 查询优化。
  3. 由于其缓存友好的特性,它非常适合大型数据集的内存排序。

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
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

算法 -

  1. 使用 heapify 进程构建最大堆。 Heapify 是一种用于维护二叉堆数据结构的堆属性的方法。
  2. 如果数组大小为 n,则包含 n//2 个父节点。
  3. 对于索引 i 处的父级:

a.它的左子节点位于索引 2i 1

b.它的右子节点位于索引 2i 2

  1. 迭代所有父级从索引 n//2 到 0 的子树,并对它们调用 heapify 函数。
  2. 现在,数组成为最大堆,最大元素位于索引 0。
  3. 将堆的第一个元素与最后一个元素交换,并将堆的大小减少 1。
  4. 重复这个过程,直到堆的长度大于1

时间复杂度:堆排序在所有三种情况下的时间复杂度均为 O(n log n):最佳、平均和最差。这是因为,无论数组是否已经排序,每次创建最大堆和交换元素时都会遵循相同的步骤。

O( log n ) - 创建最大堆

O(n) - 创建最大堆并且交换元素 n 次。

所以总时间复杂度为 O(n) * O(log n) = O(n log n)

空间复杂度:对于所有情况 - O(log n) - 对于递归堆栈。

优点 -

  1. 即使对于大型数据集,时间复杂度也是 O (n log n)。
  2. 内存使用率几乎恒定。

缺点 -

  1. 不稳定,因为它不能维持相等元素的相对顺序。
  2. 与合并排序相比,需要很多交换。

应用程序 -

  1. 对于实现频繁提取最大或最小元素的优先级队列非常有用。
  2. 在需要就地排序且内存使用至关重要的系统中很有用。
  3. 用于需要排名的场景。

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
登录后复制
登录后复制
登录后复制

算法 -

  1. 查找数组中的最大数字并确定其中的位数 (d)。如果数字的长度为 d,则在数组上调用计数排序 d 次。

  2. 对数组中的每个数字位置调用计数排序,从个位开始,然后是十位,依此类推。

  3. 计数排序:

  • 首先,创建一个索引数组,并根据元素的值映射元素。例如,如果数字为 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 是索引数组中的值的范围。

优点 -

  1. 由于元素保持其相对顺序而稳定。
  2. 如果输入范围与输入数量相同,计数排序通常比所有基于比较的排序算法(例如合并排序和快速排序)执行得更快。

缺点 -

  1. 计数排序不适用于小数值。
  2. 如果要排序的值范围很大,计数排序效率很低。
  3. 非就地排序算法,因为它使用额外的空间 O(O(n m))。

应用程序 -

  1. 它用于计算字符串中字符出现次数等应用程序。
  2. 对于对具有大范围值的整数进行排序非常有用,例如 ID 或电话号码。
  3. 可以有效地对具有多个键的数据进行排序,例如日期或元组。

以上是排序算法 ||蟒蛇 ||数据结构和算法的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Python vs.C:申请和用例 Python vs.C:申请和用例 Apr 12, 2025 am 12:01 AM

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

您可以在2小时内学到多少python? 您可以在2小时内学到多少python? Apr 09, 2025 pm 04:33 PM

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

Python:游戏,Guis等 Python:游戏,Guis等 Apr 13, 2025 am 12:14 AM

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

2小时的Python计划:一种现实的方法 2小时的Python计划:一种现实的方法 Apr 11, 2025 am 12:04 AM

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

Python:探索其主要应用程序 Python:探索其主要应用程序 Apr 10, 2025 am 09:41 AM

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

Python与C:学习曲线和易用性 Python与C:学习曲线和易用性 Apr 19, 2025 am 12:20 AM

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

Python和时间:充分利用您的学习时间 Python和时间:充分利用您的学习时间 Apr 14, 2025 am 12:02 AM

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

Python:自动化,脚本和任务管理 Python:自动化,脚本和任务管理 Apr 16, 2025 am 12:14 AM

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

See all articles