zoukankan      html  css  js  c++  java
  • NB 三人组

    NB  三人组

    1.三人行

      快排

      堆排

      归并

    快排

    思路:

    #快速排序法
    '''
        思路分析:
            1.取一个元素p,使元素p归位。
            2.列表被p分成两部分,左边都比p小,右边都比p大,
            3.递归完成排序。
                递归:第一个归位只是归为一位,所以需要递归把列表里的每一位数都归位了才能完成排序。
    
            关键点:
                1.归位
                2.递归
    
            partition函数里的逻辑:
                1.拿去左边第一个值假如是5,做比较,现在第一个位置为空
                2.从右边开始找比5小的数,放到那个空的位置。找到后移过去,自己的位置又位空,
                3.从左边找,比5大的数,移过去空的位置,以此类推。
                4.最后叠加,重合。
    
                5 1 7
    
                _ 1 7
    
                1 _ 7
    
            时间的复杂度: n*logn
            最坏情况:n*    如:987654321
            预防:随机找一个元素,就不找第一个元素,跟第一个元素对调一下。
    '''

    简单代码实现:

    def partition(li,left,right): #无序列表,最小值,最大值
        tmp =li[left]   #拿去左边第一个值
        while left < right:  #左边小于右边,就一直循环
            while left < right and li[right] >= tmp:
                right -= 1
            li[left] = li[right]    #把小于5的数,移到左边空的位置
            while left < right and li[left] <= tmp:
                left += 1
            li[right] = li[left]    #把大于的5的数,移到右边空的位置
        li[left] = tmp  #最后还需要归位。
    
        return left
    
    def _quick_sort(data,left,right):    #data=列表,左边,右边
        if left < right:    #至少两个元素,才会递归
            mid =partition(data,left,right)
            _quick_sort(data,left,mid-1)
            _quick_sort(data,mid+1,right)
    
    list = [2,3,4,1,5,6,8,9,7]
    _quick_sort(list,0,8)
    print(list)

    和系统排序比较时间效率:

    import random
    import copy
    import sys
    import time
    
    
    sys.setrecursionlimit(100000) #更改最大递归深度
    
    def cal_time(func):
        def wrapper(*args, **kwargs):
            t1 = time.time()
            result = func(*args, **kwargs)
            t2 = time.time()
            print("%s running time: %s secs." % (func.__name__, t2-t1))
            return result
        return wrapper
    
    
    def partition(li,left,right): #无序列表,最小值,最大值
        tmp =li[left]   #拿去左边第一个值
        while left < right:  #左边小于右边,就一直循环
            while left < right and li[right] >= tmp:
                right -= 1
            li[left] = li[right]    #把小于5的数,移到左边空的位置
            while left < right and li[left] <= tmp:
                left += 1
            li[right] = li[left]    #把大于的5的数,移到右边空的位置
        li[left] = tmp  #最后还需要归位。
    
        return left
    
    def _quick_sort(data,left,right):    #data=列表,左边,右边
        if left < right:    #至少两个元素,才会递归
            mid =partition(data,left,right)
            _quick_sort(data,left,mid-1)
            _quick_sort(data,mid+1,right)
    
    list = [2,3,4,1,5,6,8,9,7]
    _quick_sort(list,0,8)
    print(list)
    
    #加壳处理
    @cal_time
    def quick_sort(li):
        return _quick_sort(li,0,len(li)-1)
    
    #系统排序
    @cal_time
    def sys_sort(li):
        li.sort()
    
    li = list(range(100000))
    random.shuffle(li)
    li1 = copy.deepcopy(li)
    li2 = copy.deepcopy(li)
    
    
    sys_sort(li1)   #系统排序
    _quick_sort(li) #快排排序
    View Code

    堆排

    思路:

    #堆排序
    '''
    大根堆:一颗完全二叉树,任意节点都比其孩子节点大
    小根堆:一颗完全二叉树,任意节点都比其孩子节点少
    
    堆的性质: 
        -向下调整性质
            意思就是,左右子树都是堆,自身不是堆。
            (划分身份: 省长,市长,村站,村民)若级别构不成省长,那么就会被下调,直到形成一个堆。
            
    堆排序的过程:
        1.建立堆
        2.堆顶为最大元素
        3.去掉堆顶,将堆最后一个元素放到堆顶,通过调整,让堆有序(让省长退休,找个傀儡,进行调整)
        4.堆顶又有新值为:当前最大元素。
        5.重复以上,完成排序。
    
    详细讲解:
        1.建立堆
            一句话:农村包围城市,从叶子开始,从后往前调整。 (从村民到村长到市长到省长)
        2.后面就是挨个出数的意思。
        
    代码实现分析:
        1.i指向父亲,j指向孩子。
        
        
    '''

    代码实现:

    def sift(li,low,high):
        '''
        :param li:列表
        :param low: 堆根节点的位置
        :param high:堆最后一个节点的位置
        :return: 这是一个调整堆的过程
        '''
        i = low       #父亲的位置
        j = 2*i +1    #左孩子: 2*i +1
        tmp = li[low] #存一下省长的位置。(纪委办)
        while j <= high:  #只要有孩子就一直循环。
            if j +1 <= high and li[j+1] > li[j]: #有右孩子存在的情况下:li[j]为左孩子,li[j+1]为右孩子,若右孩子大于左孩子。
                j +=1
            if tmp < li[j]: #原省长的级别比孩子的级别小。
                li[i] = li[j]  #把孩子向上调整1级
                i = j
                j = 2*i +1
            else:
                li[i] = tmp #若纪委办的原省长级别比孩子的级别大,复职对应的省份(干部)。
                break
        else:
            li[i] =tmp   #一撸到底,回归到村民
    
    li =[2,9,7,8,5,0,1,6,4,3]
    sift(li,0,len(li)-1)
    print(li)
    
    
    def heap_sort(li):
        n = len(li)
        #1.建堆
        for i in range(n//2-1,-1,-1):
            sift(li,i,n-1)
        #2.挨个出数
        for j in range(n-1,-1,-1):
            li[0],li[j] = li[j],li[0]
            #堆的大小少了一个元素(j-1)
            sift(li,0,j-1)
    
    heap_sort(li)
    print(li)
    
    # 打印如下:
    # [9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
    # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    归并

    思路:

    #归并排序法
    '''
    根节点:头一个节点称为:'根节点'
    叶子节点: 没有孩子节点的称为:'叶子节点'
    树的深度: 从根开始往下走了几层就是: 树的深度
    节点的度: 不算节点上面的叉,只算下面的叉。
    树的度: 树包含的节点中,最大的度。
    孩子节点: 如: A分出了B   A为B的父节点   B为A的子节点
    子树: 树里面包含的子树
    
    
    归并排序分为:
        1.一次归并:
            把列表分为2段,这两段数组都是有序的,都有个指针,
            把两段数组的指针比较大小,小的移到孤儿院,小的指针交给下一位挑战者。以此类推
            
        2.归并是nb三人组里唯一不需要递归的。
            
    '''

    代码实现:

    def merge(li,low,mid,high):
        '''
        :param li: 列表
        :param low: 开头的值
        :param mid: 中间划分的值
        :param high: 结尾的值
        :return:
        '''
        i =low  #第1个有序的头值
        j =mid+1 #第2个有序的头值
        tmp=[]   #孤儿院
        while i <= mid and j <= high:
            if li[i]<li[j]:
                tmp.append(li[i])
                i +=1
            else:
                tmp.append(li[j])
                j +=1
        while  i <=mid:
            tmp.append(li[i])
            i +=1
        while  j <=high:
            tmp.append(li[j])
            j +=1
        li[low:high+1] = tmp
        # print(li[low:high+1])
    
    #递归
    def _merge_sort(li,low,high):
        if low < high:  #至少两个元素
            mid = (low+high) // 2  #两边切一半
            _merge_sort(li,low,mid)  #递归左边
            _merge_sort(li,mid+1,high) #递归右边
            merge(li,low,mid,high)  #然后merge
            # print(li[low:high + 1])
    
    def merge_sort(li):
        return _merge_sort(li,0,len(li)-1)
    
    import random
    li = list(range(10))
    random.shuffle(li)
    print(li)
    merge_sort(li)
    print(li)
  • 相关阅读:
    显示所有销售订单
    从 “香农熵” 到 “告警降噪” ,如何提升告警精度?
    KubeDL 0.4.0 Kubernetes AI 模型版本管理与追踪
    链路分析 K.O “五大经典问题”
    让容器跑得更快:CPU Burst 技术实践
    All in one:如何搭建端到端可观测体系
    【视频特辑】提效神器!如何用Quick BI高效配置员工的用数权限
    一文说清linux system load
    Flow vs Jenkins 实操对比,如何将Java应用快速发布至ECS
    实时数仓Hologres首次走进阿里淘特双11
  • 原文地址:https://www.cnblogs.com/zhongbokun/p/8690990.html
Copyright © 2011-2022 走看看