python版数据结构与算法-排序算法(一)

排序算法

在编程中,排序算法是一种将一组数据按照特定顺序进行排列的算法。
排序算法可以分为多种不同的类型,例如冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序等等。使用正确的排序算法有利于代码的可执行性.使得程序更加快速的运行
今天将介绍三种常见的排序算法:冒泡排序、选择排序和插入排序

冒泡排序:冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

# 冒泡排序
def bubble_sort(lst):
    n = len(lst)
    for i in range(n):
        for j in range(0, n-i-1):
            if lst[j] > lst[j+1]:
                lst[j], lst[j+1] = lst[j+1], lst[j]
    return lst

这是一个很简单的冒泡排序,就是一个循环,一次必交两个元素,不停的交换顺序,直到排序完成,
当使用冒泡排序算法时,需要注意以下几点:

  1. 冒泡排序的时间复杂度为O(n^2),因此在处理大量数据时可能会变得非常缓慢。如果需要处理大量数据,请考虑使用其他排序算法。

  2. 如果列表已经有序,冒泡排序仍然会继续比较和交换元素,这是不必要的操作。因此,在实现冒泡排序时,可以添加一个标志变量来表示是否发生了交换,如果没有交换,说明列表已经有序,可以直接退出循环。

  3. 冒泡排序是一种稳定的排序算法,它不会改变相等元素的相对顺序。

  4. 冒泡排序是一种原地排序算法,它不需要额外的存储空间来存储临时变量。

  5. 冒泡排序的稳定性和原地排序特性使得它在某些场景下非常有用,例如对于小规模的数据集进行排序。

上面冒泡排序还可以改进一下

def bubble_sort(nums):
    if not nums or len(nums) == 1:
        return nums[:]
    for i in range(len(nums)-1):
        flag = True
        for j in range(len(nums)-1-i):
            if nums[j] > nums[j+1]:
                nums[j], nums[j+1] = nums[j+1], nums[j]
                flag = False
        if flag:
            break
    return nums[:]

第一次循环的时候,给他加一个flag,当flag为false的时候,表示发生了交换,如果flag为true,说明列表已经有序,那么就排序完成.

选择排序:选择排序是一种简单直观的排序算法。
它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法。

# 选择排序
def selection_sort(lst):
    n = len(lst)
    for i in range(n):
        min_index = i
        for j in range(i+1, n):
            if lst[min_index] > lst[j]:
                min_index = j
        lst[i], lst[min_index] = lst[min_index], lst[i]
    return lst
选择排序的时间复杂度为O(n^2),空间复杂度为O(1)
虽然选择排序在某些情况下表现良好,但它不稳定

因为相等的元素可能会改变它们的相对顺序。这是因为在选择排序过程中,我们总是将当前未排序部分的第一个元素与已排序部分的第一个元素进行比较,并将其放到正确的位置上。如果已排序部分的第一个元素比当前未排序部分的第一个元素小,那么它们之间的相对顺序就会被改变。

实际应用中,建议使用稳定的排序算法,例如插入排序、归并排序、快速排序等。这些算法的时间复杂度和空间复杂度都比选择排序要好,并且具有更好的稳定性。

插入排序:插入排序是一种简单直观的排序算法。
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。


# 插入排序
def insertion_sort(lst):
    n = len(lst)
    for i in range(1, n):
        key = lst[i]
        j = i-1
        while j >=0 and key < lst[j] :
                lst[j+1] = lst[j]
                j -= 1
        lst[j+1] = key
    return lst

使用插入排序算法时,有一些需要注意的方面:

  1. 插入排序的时间复杂度为O(n^2),因此在处理大量数据时可能会变得非常缓慢。如果需要处理大量数据,请考虑使用其他排序算法
  2. 在实现插入排序时,需要注意元素的相对顺序。具体来说,对于相等的元素,插入排序会将后面的元素插入到前面的元素之前,因此插入排序是一种稳定的排序算法。
  3. 插入排序是一种原地排序算法,它不需要额外的存储空间来存储临时变量。
  4. 插入排序在处理已经有序或近似有序的列表时具有较好的性能。因此,在实际应用中,可以通过对列表进行预处理,使其接近有序状态,从而提高插入排序的效率。
  5. 插入排序可以通过二分查找来优化,使其时间复杂度降为O(nlogn)。这种优化通常称为“二分插入排序”。

二分查找会在后续的内容里进行展示.

欢迎阅读,如果你对我的文章有什么建议,欢迎给我留言

你可能感兴趣的:(排序算法,python,算法,leetcode)