• 算法


    1.算法基础

    算法(Algorithm):一个计算过程,解决问题的方法

    递归回顾

    递归式不能用函数装饰器的!如果你强用递归一次会执行一次你的幻术装饰器
    
    避免这种情况可以在你使用的函数上加一层函数
    
    
    例如:
    import functools
    import random
    import time
    import sys
    import os
    # 设置系统的最大递归限制
    sys.setrecursionlimit(1000000)
    
    
    def run_time(func):
        """
        为了装饰别的函数,统计函数执行的时间统计
        :param func:
        :return:
        """
        @functools.wraps(func)
        def wrapper(*args,**kwargs):
            # 开始时间
            start_time = time.time()
            # 调用被装饰的函数
            res = func(*args,**kwargs)
            # 结束时间
            end_time = time.time()
            # 打印输出,更佳的方法是将其写入到log中
            print( "%s 函数的执行时间为: %s s" %(func.__name__,end_time - start_time))
            return res
        return wrapper
    
    
    @run_time
    def fast_sort_1(data_list):
        """
        因为快排包含递归,所以不能直接被装饰,套一层外壳
        :param data_list:
        :return:
        """
        return fast_sort_basic1(data_list)
    
    
    def fast_sort_basic1(data_list):
        """简单的快速排序,消耗内存,空间复杂度略高"""
        if len(data_list) == 0:
            # 如果传过来的数据为[],直接返回
            return [ ]
        else:
            # 把第一个数据拿出来,
            # 比它小的数据放在左边,再次调用本函数                        +   第一个数据   +    比它小的数据放在右边,再次调用本函数
            return fast_sort_basic1([i for i in data_list[1:] if i < data_list[0]]) +  [data_list[0]] +  fast_sort_basic1([i for i in data_list[1:] if i > data_list[0]])
    友情提示 递归使用函数装饰器
    递归 红色预警
     1 使用递归完成 (抱着抱着我的小鲤鱼的我的我)
     2 def output(cod,code=''):
     3     if cod==0:
     4         code += '我的小鲤鱼'
     5     else:
     6         code +='抱着'
     7         code=output(cod - 1, code)
     8 
     9         code += '的我'
    10     return code
    11 
    12 
    13 
    14 
    15 re=output(2,'')
    16 print(re)
    递归

    2.时间复杂度

    时间复杂度是用来估计算法运行时间的一个式子(单位)。
    一般来说,时间复杂度高的算法比复杂度低的算法慢
    常见的时间复杂度(按效率排序)
    O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)
    不常见的时间复杂度(看看就好) O(n!) O(2n) O(nn) …
    如何一眼判断时间复杂度?
      循环减半的过程O(logn)
      几次循环就是n的几次方的复杂度
     print('Hello World')
    O(
    1for i in range(n):
      print('Hello World') O(n)
    O(n2) for i in range(n):
      print('Hello World') O(n3) while n > 1:
      print(n)
    n = n // 2 O(logn)

    3.递归二分查找:

    # 原理:必须是有序时间复杂长度O(lognn)
    # 1.循环取最数列最中间的数据
    # 同查找数据进行比较 如果比找的数据小,则把最后一个数据的位置提到中间位置-1,
    # 同查找数据进行比较 如果比找的数据大,则把最后一个数据的位置提到中间位置+1
    # 2.如果第一个位置的数据大于最后一个 执行完毕 没有找到
    # 如果中间查找到终止

    def bin_search(list_data, num):
    l = 0
    r = len(list_data) - 1
    mid = (l + r) // 2
    if list_data[mid] == num:
    return mid
    elif list_data[mid] > num:
    high = mid - 1
    else:
    l = mid + 1

    4.低级排序

    1.冒泡排序(时间复杂度O(n2))常用
    '''
    冒泡排序原理:
        一个指针指向当前数,如果当前数比下一个数据大 ,交换位置,指针往下走一帧
        当前数比下一个数小,则指针往下走,当前数为指针所指向当数,和下一个数据比较
        直到最后一个产生至少一个有序数据
        指针再次回到第一个数据,重复动作
    '''
    
    def bubble_sort(list_data):
        for i in range(len(list_data)-1):
            flag=True
            for j in range(len(list_data)-i-1):
                if list_data[j]>list_data[j+1]:
                    list_data[j],list_data[j+1]=list_data[j+1],list_data[j]
                    flag =False
            if flag:
                return 
    View Code
    2.选择排序(时间复杂度O(n2))
    '''
    选择排序原理:
    先把左边第一个数当成最小的一个
    进行便利所有的数据只要遇到比他小的就进行调换,直到完成一轮第一个最小
    下一个依旧这样从当前的下一个进行便利调换
    '''
    def select_sort(li):
        for i in range(len(li)-1):
            min_loc=i
            for j in range(i+1,len(li)):
                if li[j]<li[min_loc]
                    min_loc=j
            if min_loc !=i:
                li[i],li[min_loc]=li[min_loc],li[i]
    View Code
    3.插入排序(时间复杂度O(n2))
    '''
    插入排序原理:
    数据中从左到右分为有序和无序区
    先把第一个数当做有序的
    下个数据从当前位置向前依次比较 遇到比自己小的第一个进行调换位置
    依次编程有序的
    '''
    
    def insert_sort(list_data):
        for i in range(1,len(list_data)):
            tep=list_data[i]
            j=i-1
            while j>=0 and tep <list_data[j]:
                list_data[j+1]=list_data[j]
                j=j-1
            list_data[j+1]=tep
    View Code

     5.快排

    option 1

    
    

    import functools
    import random
    import time
    import sys
    import os
    # 设置系统的最大递归限制
      sys.setrecursionlimit(1000000)

    def fast_sort(list_data):
        '''原理用内存还速度简单的快速排序,消耗内存,空间复杂度略高
            以第一个数据为分界线 分为两部分左边 比中间的小 右边的比中间的大第一波下来找到最中间的值,并且分开大小
            把左边的列表再次执行,分为三部分你, 右边的同样执行
        '''
        if len(list_data) == 0:
            return []
        else:
            # 比它小的数据放在左边,再次调用本函数                        +   第一个数据   +    比它小的数据放在右边,再次调用本函数
            return fast_sort([i for i in list_data[1:] if i < list_data[0]]) + list_data[0] + fast_sort(
                [i for i in list_data[1:] if i > list_data[0]])
    
    
    import random
    
    if __name__ == '__main__':
        a = list(range(33))
    
        random.shuffle(a)
        # print(a)
        c = fast_sort_basic1(a)
        print(c)

    option 2 不消耗内存

    def fast_sort2(data,left,right):
    
        if left<right:
            # 调用partiton函数 mid 处为第一个元素应该待的地方
            mid =partition(data,left,right)
    
            # 对左边的数据继续做快速排序
            fast_sort2(data,left,mid-1)
            # 对右边的数据继续做快速排序
            fast_sort2(data,mid+1,right)
        return data
    
    
    
    def partition(data,left,right):
        """
        找中间值
        将数据的左边的第一个数据,数据调整为自己应该待的位置
        [5,2,1,4,3]      从第一个数字开始,把它放在它应该在的位置,什么叫它应该在的位置,就是左边的数字都比它小,右边的数字都比它大
    
        1、从最右边开始找,找到第一个比它小的数 和 它 交换位置,把第一个数字放到新的位置
        2、然后从这个新的位置, 左边开始找比它大的数字,和它大小比较,然后和新的位置交换
        3、不断重复,就会使第一个数字出现在它应该出现的位置
        那么这个数字所在的位置就是有序区
    
        """
        # 找到左边的第一个数据
        tmp = data[left]
        # 一直循环直到这个数据待在它自己该待的位置
        while left < right:
            # 从右边开始找数据
            while data[right] > tmp and left < right:
                # 找不到,继续往左找
                right = right -1
            # 右边找到一个比它小,赶紧交换位置
            data[left] = data[right]
            # 从左边开始找数据
            while data[left] < tmp and left < right:
                # 找不到继续往右找
                left = left + 1
            # 左边找到一个比它大的赶紧交换位置
            data[right] = data[left]
        # 此时此刻左边和右边完全相同
        # 这个数据已经待在它该待的位置
        data[left] = tmp
        return left
    
    
    import random
    
    if __name__ == '__main__':
        a = list(range(12))
    
        random.shuffle(a)
        print(a)
        c = fast_sort2(a,0,len(a)-1)
        print(c)
  • 相关阅读:
    racle SQL性能优化
    Oracle 删除重复数据只留一条
    oracle存储过程常用技巧
    详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名及手工脚本创建oracle数据库
    用友ERP-U8最新破解(再次更新版本,附安装过程中的解决办法)
    轻松三步教你配置Oracle—windows环境
    非常好的Oracle教程【转】
    Oracle新表使用序列(sequence)作为插入值,初始值不是第一个,oraclesequence
    大数据学习资源汇总
    Index
  • 原文地址:https://www.cnblogs.com/honglingjin/p/6865800.html
Copyright © 2020-2023  润新知