首页 > 其他分享 >排序法:选择、冒泡、插入和快排

排序法:选择、冒泡、插入和快排

时间:2024-04-11 09:34:37浏览次数:23  
标签:数列 list 无序 快排 冒泡 排序 my 数字

排序方法指的是对一个无序的数列,按照一定方法让其变得有序。排序法重点是思维过程,本文中的四种排序方法都较为基础,但其中蕴含的算法思维各不相同,适合作为算法入门学习内容。

  • 选择排序法
    我认为选择排序法是较符合一般人思维模式的排序法,它是指对于每个数列,从其中找出最小的一个数字,将其放至首位,然后再不断对剩余的无序数列重复此操作。当剩余无序数列的长度为0时,则完成排序。其python实现代码如下:
点击查看代码
def select_sort(my_list):  
    n= len(my_list)        # n为数列长度
    for i in range(n-1):   # 共进行n-1次选择(外循环),因为只要选出最小的n-1个数,最大的数就是剩下的,不需要进行额外操作天然已经位于数列末端
        min_i = i          # 初始化最小数字的索引为无序数列的第一个元素的索引,即假设第一个数字现在就是最小值。
        for j in range(i+1,n):  # 内循环处理无序数列中的每一个元素 
            if my_list[j]<my_list[min_i]:    #一旦无序数列中的数字比我们假设的初始值小,就将其索引记录下来
                min_i = j
        if min_i != i:     # 一次内循环完成后,已经将无序数列中最小值的索引赋值给了min_i,如果其不同于无序数列的最左端(第一个)数字,则将两者交换。交换完成后最小值已位于无序数列的最左段,此时可以将其视为有序数列的最右端,而不再是无序数列的一部分(通过外循环i的不断增加来实现)
            my_list[i],my_list[min_i] = my_list[min_i],my_list[i]
选择排序的时间复杂度O(n^2)
  • 冒泡排序法
    冒泡排序的过程是每次将最大的一个元素放至队列末尾,这听起来很像选择排序的反过程。但是冒泡排序的实现是完全不同的。每一次排序,都是将无序数列的每一位,依次与其右边的元素进行比较,并将其中较大的数字放在右边。如此操作,大的数字会不断被向右移,直至遇到比他更大的数字。这个更大的数字会接过其接力棒,再次向右进行比较,直到到达无序数列的最后一位。代码实现如下:
点击查看代码
def bubble_sort(my_list):
    listlen = len(my_list)
    for i in range(listlen-1):  # i 代表轮次,范围为0到n-2共n-1次(最大的n-1个数字排完无需再排第n个)
        for j in range(listlen-1-i):   # j 为每轮进行比较的第一个数字,因为最后的i个数字已经完成了排序,所以每次都是比较(n-1)-i个数字即可。对于第一轮
            if my_list[j]>my_list[j+1]: # 如果比右边数字大,则进行交换
                my_list[j],my_list[j+1]=my_list[j+1],my_list[j]
冒泡排序的时间复杂度O(n^2)
  • 插入排序
    插入排序是指将每个序列分为左右两个部分,左边是已经从小到大排序完成的数列,右边是无序数列,依次将无序数列的第一位插入至有序数列中。对于一个未经过排序的数列,可以将第一个数字视作有序的(很显然单独一个数字必然是有序的),而将第二个数字开始的剩余数字视为需要排序的无序数列。代码实现如下:
点击查看代码
def insert_sort(my_list):
    n = my_list
    for i in range(1,n):             # i 表示现在要处理第i个数字(第0)位不需要处理,在处理完这n-1个数字后它会天然出现在应该出现的位置
        for j in range(i+1,0,-1):    # j 指示要进行比较的数字,每次与左边的数字进行比较,如果小于左边数字说明应该左移
            if my_list[j]<my_list[j-1]:
                my_list[j],my_list[j-1] = my_list[j-1],my_list[j]
            else:
                break
插入排序的时间复杂度为O(n^2)
  • 快速排序
    快速排序的逻辑很简单,但是代码实现会稍微复杂一点。原理是:随便选取一个数字,将数列中比其小的数字都放到它左侧,比它大的数字都放在它右侧,以此来确定其在数列中的位置;之后,再对于每个没有确定下来的数列区间重复此操作,直至每个数字都位于正确的位置。快排使用了递归的方式去排序,代码实现如下:
点击查看代码
def quick_sort(my_list,start,end):
    """
    快速排序
    :param my_list: 要排序的列表
    :param start: 表示从哪个位置开始排序
    :param end: 表示到哪个位置结束排序
    :return: 如果start>=end,则表示排序完成,否则需要继续排序
    """
    if start >=end:  # 当一个区间的长度为1或0时,说明已经排好序,则直接返回
        return
    left = start  #左指针为区间的第一个元素
    right = end   #右指针
    mid = my_list[start]   # 选取第一个元素作为中间值(基准值)。此时左指针位置空出来了
    while left < right:    # 左右指针向中间移动,直到左右指针相遇
        while my_list[right]>=my_list and left <right:  # 右指针向左移动,直到遇到小于等于基准值的元素
            right-=1
        my_list[left] = my_list[right]   # 将小于等于基准值的元素放到左指针位置
        while my_list[left]<my_list and left <right:   # 左指针向右移动,直到遇到大于等于基准值的元素
            left+=1
        my_list[right] = my_list[left]   # 将大于等于基准值的元素放到右指针位置
    my_list[left] = mid   # 经过上述的两次交换之后,可能存在两种情况:1.左右指针相遇;2.左指针的值已经赋给了右指针的位置。无论哪种情况,都需要将基准值放到左指针的位置。
    # 递归左半区间。如果 start=left-1,说明这次排序完之后左半区只有一个元素,不需要再排序。如果start>left-1,说明左半区为空,不需要再排序。
    quick_sort(my_list,start,left-1)
    quick_sort(my_list,right+1,end)      # 递归右半区间

标签:数列,list,无序,快排,冒泡,排序,my,数字
From: https://www.cnblogs.com/maninfirer/p/18127916

相关文章

  • (Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断
    前言本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。堆排序(HeapSort)概念堆排序是一种基于堆数据结构的排序算法,其核心思想是将待排序的序列构建成一个最大堆(或最小堆),然后将堆顶元素与最后一个元素交换,再将剩余元素重新调整为最大堆(或最小堆),重复......
  • 归并排序,时间复杂度O(n*logn),空间复杂度O(n),是稳定算法
    空间复杂度原因是因为需要额外数组空间来进行排序时间复杂度T(n)=2T(n/2)+O(n),a=2,b=2,c=1根据master公式可知时间复杂度O(nlogN)归并排序可以排序数据量很大的数组,举例说明,例如要排序有2^64个数字的数组,那么归并排序将会开辟64层系统栈,这并不会导致栈溢出.include<stdio......
  • HarmonyOS 开发-阻塞事件冒泡
    介绍本示例主要介绍在点击事件中,子组件enabled属性设置为false的时候,如何解决点击子组件模块区域会触发父组件的点击事件问题;以及触摸事件中当子组件触发触摸事件的时候,父组件如果设置触摸事件的话,如何解决父组件也会被触发的问题。效果图预览使用说明:开启使能开关,在点击事......
  • Oracle分析函数- count()/sum() over(partition by 分组 order by 排序) 详解
    优点:代码简单明了,并且执行效率高,(不影响总的记录数)如果不用这种函数去写,按照平时我们的思路首先想到的可能是子查询,那么将至少会走4次以上的全表扫描:(1)每个订单中产品数量大于3的产品至少1个(003,004)(2)每个订单中折扣标志为'1'的产品至少有2个(002,004)(3)每个订单......
  • javaScript-sort()排序
    在写题的时候要以列表中的某个参数进行排序letlist=[{age:10,name:'x1'},{age:8,name:'x2'},{age:20,name:'x3'},{age:9,name:'x4'},{age:30,name:'x5'},]就用到了list.sort((a,b)=>a.age-b.age)但是我搞不清楚如何来判断是......
  • NzN的数据结构--插入排序
         排序排序我要Disney,今天我们先来看看经典排序算法里的插入排序,先三连后看才是好习惯!!!目录一、排序的概念及应用1.排序的概念2.排序的应用3.常见的排序算法二、插入排序1.基本思想2.直接插入排序3.希尔排序(缩小增量排序)一、排序的概念及应用1.......
  • 排序之插入排序和交换排序
    排序的分类内部排序插入排序直接插入排序折半插入排序希尔排序交换排序冒泡排序快速排序选择排序简单选择排序堆排序⭐归并排序基数排序外部排序插入排序直接插入排序在待排序的元素序列基本有序的前提下,直接插入排序是效率最高的排序算法利用直接插入排序的......
  • Java入门基础知识第八课(数组)——冒泡排序、Arrays工具类
    前面二白讲了关于数组的概念、语法以及简单的输入输出,实际上关于数组的知识还有很多,接下来咱们讲一下冒泡排序以及一些常用的Arrays工具类,需要记忆的知识很多,而且容易混淆。一、冒泡排序简介(原理)升序为例:从头开始,每次比较相邻两数小的交换到前面每轮结束后最大的数交换到......
  • 每日一题:C语言经典例题之平方和排序
    题目描述输入int类型范围内的N个非负整数,要求按照各个整数的各数位上数字的平方和从小到大排序,若平方和相等,则按照数值从小到大排序。例如,三个整数9、31、13,各数位上数字的平方和分别为81、10、10,则排序结果为13、31、9。输入测试数据有多组。每组数据先输入一个整数N(0<N<1......
  • ROS笔记Day04----服务通信(实现排序--xxb第二次作业)
    一、服务通信简介服务通信是基于请求响应模式的,是一种应答机制。一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A。服务通信适用于实时性要求比较高的场景,例如设计一款自动搭讪机器人,每当摄像头检测到有搭讪目标出现,则摄像头这个节点就会向底盘......