数据结构与算法-排序

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

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

  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)

相关推荐
wfeqhfxz25887821 小时前
YOLO13-C3k2-GhostDynamicConv烟雾检测算法实现与优化
人工智能·算法·计算机视觉
Aaron15882 小时前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理
Queenie_Charlie2 小时前
前缀和的前缀和
数据结构·c++·树状数组
_不会dp不改名_3 小时前
leetcode_3010 将数组分成最小总代价的子数组 I
算法·leetcode·职场和发展
你撅嘴真丑5 小时前
字符环 与 变换的矩阵
算法
早点睡觉好了5 小时前
重排序 (Re-ranking) 算法详解
算法·ai·rag
gihigo19985 小时前
基于全局自适应动态规划(GADP)的MATLAB实现方案
算法
念越6 小时前
数据结构:栈堆
java·开发语言·数据结构
dear_bi_MyOnly6 小时前
【多线程——线程状态与安全】
java·开发语言·数据结构·后端·中间件·java-ee·intellij-idea
ctyshr6 小时前
C++编译期数学计算
开发语言·c++·算法