数据结构与算法-排序

排序算法是数据结构的与算法中的一个基础算法。
介绍:所谓排序,使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作,排序算法,就是如何使得记录按照要求排列的方法。

分类:算法的种类有很多,主要是一下四种:

  1. 冒泡排序
  2. 选择排序
  3. 插入排序
  4. 快速排序

冒泡排序

思想:重复走访每个要排序的元素,与其相邻元素挨个进行比较,若前一个元素比后一个元素大,则交换位置,依次遍历完所有元素后,最大的元素就在最后一个位置冒泡了。然后只需要重复上述步骤即可将全部元素排序完成。

冒泡排序代码实现:

python 复制代码
def bubble_sort(my_list):
    """
    冒泡排序
    :param my_list:传入的待排序的数组
    :return:None
    """
    # 外层循环
    for i in range(len(my_list) - 1):
        # 记录内循环交换次数
        count = 0
        # 内层循环
        for j in range(len(my_list) - 1 - i):
            # 若与后一个元素相比,前一个更大,则交换位置
            if my_list[j] > my_list[j + 1]:
                # 交换次数加1
                count += 1
                my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]
        # 若没有元素交换位置,则终止循环
        if count == 0:
            break

通过代码不难看出,当传入数组刚好是按照大小排序时,count = 0,提前终止循环,因此最优时间复杂度为O(n)。当数组完全乱去时,两层循环都需要遍历n-1次,因此时间复杂度为O(n**2)

选择排序

思想:第一次从序列中选出最小或最大的元素,将它放在序列的起始位置或尾部,然后从剩余元素中继续寻找,重复上述步骤,直到全部元素都排序完成。

选择排序代码实现:

python 复制代码
def select_sort(my_list):
    """
    选择排序
    :param my_list:传入的待排序的数组
    :return:排序的次数
    """
    count = 0
    # 外循环
    for i in range(len(my_list) - 1):
        # 最小值下标索引
        min_index = i
        # 内循环
        for j in range(i + 1, len(my_list)):
            # 如果找到更小的元素,则更新最小值下标索引
            if my_list[j] < my_list[min_index]:
                min_index = j
            # 如果最小值下标索引和当前索引不相等,则交换位置
            if min_index != i:
                my_list[i], my_list[min_index] = my_list[min_index], my_list[i]
                count += 1
    return count

通过代码不难看出,无论顺序如何,代码都需要进行两次n-1的循环,时间复杂度为O(n**2),但是其只是在原始数组中进行一次交换,因此空间复杂度为O(n)

插入排序

思想:将待排序的元素与以排序元素比较,找到合适的位置插入到已排序元素中。

插入排序代码实现:

python 复制代码
def insert_sort(my_list):
    """
    插入排序
    :param my_list:传入的待排序的数组
    :return:排序后的数组
    """
    # 外层循环
    for i in range(1, len(my_list)):
        # 内层循环,从后往前比较
        for j in range(i , 0, -1):
            if my_list[j] < my_list[j - 1]:
                my_list[j], my_list[j - 1] = my_list[j - 1], my_list[i]
            else:
                 break
    return my_list

插入排序在列表有序的情况下,只需要遍历一遍数组就可以得到排序结果,因此最好时间的复杂度为O(n),在列表无序的情况下,则需要变量两层n-1循环,最坏时间复杂度为O(n**2)

快速排序

思想:首先选择最左侧元素作为中间元素,遍历列表,逐个比较元素与中间元素的大小,将比中间元素小的元素放在左侧,将比中间元素大的元素放在右侧。然后将列表按照中间值进行拆分为两份,分别对左右两次列表进行上述相同的步骤,依次循环,直到列表排序完成。

快速排序代码实现:

python 复制代码
def quick_sort(my_list, start, end):
    """
    快速排序
    :param my_list:传入的待排序的数组
    :param start:待排序的数组的起始索引
    :param end:待排序的数组的结束索引
    :return:None
    """
    # 设置递归终止条件
    if start >= end:
        return
    # 设置左指针
    left = start
    # 设置右指针
    right = end
    # 将左侧值作为中间基准值
    middle = my_list[left]
    # 当左侧索引小于右侧索引时,进入循环。
    while left < right:
        # 右侧元素比中间值大时,右指针像左移动
        while left < right and my_list[right] >= middle:
            right -= 1
        # 右侧元素比中间值小时,将右指针指向元素赋值给左指针
        my_list[left] = my_list[right]
        # 左侧元素比中间值小时,左指针向右移动
        while left < right and my_list[left] < middle:
            left += 1
        # 左侧元素比中间值大时,将左指针指向元素赋值给右指针
        my_list[right] = my_list[left]
    # 将中间值赋给中间索引
    my_list[left] = middle
    # 递归调用
    quick_sort(my_list, start, left - 1)
    quick_sort(my_list, left + 1, end)

快速排序的思路和选择排序类似,但是选择排序每次选择一个元素作为中间值,而快速排序每次选择最左侧元素作为中间值,因此最优时间复杂度为O(nlogn),最坏时间复杂度为O(n),空间复杂度为O(logn)

相关推荐
星火开发设计3 分钟前
C++ deque 全面解析与实战指南
java·开发语言·数据结构·c++·学习·知识
neardi临滴科技7 分钟前
从算法逻辑到芯端落地:YOLO 目标检测的进化与瑞芯微实践
算法·yolo·目标检测
小雨下雨的雨7 分钟前
Flutter跨平台开发实战:鸿蒙系列-循环交互艺术系列——瀑布流:不规则网格的循环排布算法
算法·flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨9 分钟前
Flutter跨平台开发实战: 鸿蒙与循环交互艺术:跑马灯的无极滚动算法
算法·flutter·华为·交互·harmonyos·鸿蒙
charliejohn3 小时前
计算机考研 408 数据结构 树形查找 相关概念及计算题例题
数据结构·考研
NAGNIP8 小时前
一文搞懂机器学习中的特征降维!
算法·面试
NAGNIP8 小时前
一文搞懂机器学习中的特征构造!
算法·面试
Learn Beyond Limits9 小时前
解构语义:从词向量到神经分类|Decoding Semantics: Word Vectors and Neural Classification
人工智能·算法·机器学习·ai·分类·数据挖掘·nlp
你怎么知道我是队长9 小时前
C语言---typedef
c语言·c++·算法
Qhumaing10 小时前
C++学习:【PTA】数据结构 7-1 实验7-1(最小生成树-Prim算法)
c++·学习·算法