zoukankan      html  css  js  c++  java
  • 04-10大排序

    十大经典排序算法

    https://mp.weixin.qq.com/s/putWU_FBF7cZJkuVpCy0sw

    img

    1.冒泡

    def bubble_sort(data):
        for i in range(len(data)-1):
            exchange = False
            for j in range(len(data)-i-1):
                if data[j]>data[j+1]:
                    data[j],data[j+1]=data[j+1],data[j]
                    exchange=True
            if not exchange:  # 一趟没有交换,说明data是有序的
                return data
        return data
    

    2.快排

    def once_sort(data,left,right):
        temp = data[left]       # 选出第一个元素作为temp
        while left<right:
            while left<right and data[right]>temp:
                right -=1
            data[left]=data[right]
    
            while left<right and data[left]<temp:
                left+=1
            data[right]=data[left]
    
        data[left]=temp
        return left
    
    def quick_sort(data,left,right):
        if left<right:
            mid = once_sort(data,left,right)
            data = quick_sort(data,left,mid-1)   # temp左边排序
            data = quick_sort(data,mid+1,right)  # temp右边排序,不用管mid
        return data
    

    3.选择排序

    li = [4,5,6,,7,8,9,9,54]
    1、选择 li[0:n],最小下标为0,找出最小的元素,所对应的下标与0交换,交换值
    2、选择 li[1:n], 最小下标为1,找出最小的元素,所对应的下标与1交换,交换值
    3、反复
    
    def select_sort(data):
        for i in range(len(data)-1):  # 当前N-1个数字排列好了,最后一个也就好了
            min_index = i
            for j in range(i+1,len(data)):  # [1~n]
                if data[j]<data[min_index]:
                    min_index = j           # 最小下标交换
    
            if min_index != i:
                data[min_index],data[i]=data[i],data[min_index]
    
        return data
    

    4.插入排序

    li = [43,34,354,342,21]
    1、把第一个当做有序区,其他作为无序区
    2、从[1:n]开始,选取temp=li[i], j =i-1
    3、li[i],与li[i-1]比较 , 每次与前一个比较
    4、若li[i]比temp大的话,li[i]向后移动1位
    
    def insert_sort(data):
        for i in range(1,len(data)):
            temp = data[i]  # 取出当前为未排序的数
            j = i-1
            while j>=0 and data[j]>temp:  # 未排序的temp < 排序的数
                data[j+1]=data[j]        # 排序好的数,往后移一位
                j -= 1
            
            data[j+1] = temp  # 未排序的temp > 排序的数,将temp插入到空出的位置
    
        return data
    

    5.希尔排序

    分组插入排序
    1、分组标准gap=len(data)//2,gap//=2
    2、插入排序
    3、gap替换1
    
    def shell_sort(data):
        gap = len(data)//2  # 取li长度的1/2
        while gap>0:
            # 插入排序 gap ---> 1
            for i in range(gap,len(data)):
                temp = data[i]
                j = i-gap
                while j >= 0 and data[j]>temp:
                    data[j+gap]=data[j]
                    j -= gap
                data[j+gap] = temp
        
            gap //= 2
    
        return data
    

    6.二路归并排序

    二路归并
    1. 先分解
        将列表分解成一个个元素
    2. 再合并
        合并成 2段有序列表,列表越来越大
    
    # merge 
    英 [mɜ:dʒ]      美 [mɜ:rdʒ]      
    融入;(使)混合;相融;渐渐消失在某物中 
    
    def merge(data,left,mid,right):
        temp = []
        i,j = left,mid+1
    
        # 两段有序,[left~mid]   [mid+1~right]
        while i<=mid and j<=right:
            if data[i]<data[j]:
                temp.append(data[i])
                i+=1
            else:
                temp.append(data[j])
                j+=1
        
        # 一段已经为空
        while i<=mid:      # i=mid也是要计算的 
            temp.append(data[i])
            i+=1
        while j<=right:    # j=mid+1,没有=的话,就会漏掉mid
            temp.append(data[j])
            j+=1
    
        # temp赋值给data[left:right]
        data[left:right+1] = temp
        return data
    
    
    def merge_sort(data,left,right):
        if left<right:
            mid = (left+right)//2
    
            # 分解
            merge_sort(data,left,mid)
            merge_sort(data,mid,right)
    
            # 合并
            merge(data,left,mid,right)
    
        return data
    

    7.堆排序

    1.根据列表,构造堆,调整使堆有序
    2.得到堆顶元素,为最大元素,去掉堆顶
    3.将堆最后一个元素放到堆顶
    4.调整使堆有序,堆顶元素为第二大元素
    5.重复3
    

    非线性排序:通过比较元素间的相对次序,复杂度不能突破O(nlogn)

    线性排序:可以达到线性时间运行

    8.计数排序

    抽屉原理,统计每个数出现的次数
    小范围:输入的数据必须是有确定范围的整数。
    时间复杂度O(n+k)   n个0~k之间的整数
    空间复杂度O(n+k)
    
    1.找出待排序数组的min,max
    2.创建max+1长度的数组空间,元素初始化为0
    3.统计重复元素出现的次数
    4.对所有的计数累加
    5.反向填充目标数组
    

    9.桶排序

    鸽巢排序,稳定
    要求:data服从均匀分布
    时间复杂度:当n=k时,达到O(n), O(n+k), 最坏O(n^2)
    空间复杂度: O(n+k)
    
    步骤:
    1.设置一个定量的数组当作空桶;
    2.遍历输入数据,并且把数据一个一个放到对应的桶里去;
    3.对每个不是空的桶进行排序;
    4.从不是空的桶里把排好序的数据拼接起来。
    

    10.基数排序

    时间复杂度:O(n*k)  k为关键字
    空间复杂度: O(n+k)
    
    1.按照低位先排序,然后收集
    2.按照高位排序,再收集
    3,依次类推
    
  • 相关阅读:
    逆向
    BUUCTF
    学校健康系统自动打卡
    SQL数据库操作练习(3)
    简单尝试UPX脱壳
    网站WAF-安全狗的绕过(一)
    【题解】担心
    【题解】树上的鼠
    【题解】CF1299B Aerodynamic
    【题解】等你哈苏德
  • 原文地址:https://www.cnblogs.com/venicid/p/9751576.html
Copyright © 2011-2022 走看看