zoukankan      html  css  js  c++  java
  • 算法分类 ,时间复杂度 ,空间复杂度,优化算法

    算法

        今天给大家带来一篇关于算法排序的分类,算法的时间复杂度,空间复杂度,还有怎么去优化算法的文章,喜欢的话,可以关注,有什么问题,可以评论区提问,可以与我私信,有什么好的意见,欢迎提出.

    前言: 算法的复杂度分为时间复杂度与空间复杂度,时间复杂度指执行算法需要需要的计算工作量,空间复杂度值执行算法需要的内存量,可能在运行一些小数据的时候,大家体会不到算法的时间与空间带来的体验. 优化算法就是将算法的时间优化到最快,将空间优化到最小,假如你写的mod能够将百度游览器的搜索时间提升0.5秒,那都是特别厉害的成绩.

    本章内容:   1,算法有哪些   2,时间复杂度,空间复杂度   3,优化算法   4,算法实例

    一,算法有哪些

      常见的算法有冒泡排序,快排,归并,希尔,插入,二分法,选择排序,广度优先搜索,贪婪算法,这些都是新手入门必须要了解的,你可以不会,但是你必须要知道他是怎么做到的,原理是什么,今天就给大家讲一讲我们常用的冒泡排序,选择排序,这两个排序算法,

    1,冒泡排序(Bubble Sort), 为什么叫他冒泡排序呢? 因为他就像是从海底往海面升起的气泡一样,从小到大,将要排序的数从小到大排序,

    冒泡的原理: 他会一次比较两个数字,如果他们的顺序错误,就将其调换位置,如果排序正确的话,就比较下一个,然后重复的进行,直到比较完毕,

    这个算法的名字也是这样由来的,越大的数字,就会慢慢的'浮'到最顶端. 好了该上代码了,下面就是冒泡排序的代码,冒泡相对于其他的排序算法来说,比较的简单,比较好理解,运算起来也是比较迅速的,比较稳定,在工作中也会经常用到,推荐使用

    # 冒泡排序
    def bubble_sort(alist):
        n = len(alist)
        # 循环遍历,找到当前列表中最大的数值
        for i in range(n-1):
            # 遍历无序序列
            for j in range(n-1-i):
                # 判断当前节点是否大于后续节点,如果大于后续节点则对调
                if alist[j] > alist[j+1]:
                    alist[j], alist[j+1] = alist[j+1], alist[j]
    if __name__ == '__main__':
        alist = [12,34,21,56,78,90,87,65,43,21]
        bubble_sort(alist)
        print(alist)
    # 最坏时间复杂度: O(n^2)
    # 最优时间复杂度: O(n)
    # # 算法稳定性:稳定

       

    2,选择排序(selection sort)

        选择排序(selection sort)是一种简单直观的排序方法, 他的原理是在要排序的数列中找到最 大 或者最 小 的 元素,放在列表的起始位置,然后从其他里找到第二大,然后第三大,依次排序,

    依次类,直到排完,

        选择排序的优点是数据移动, 在排序中,每个元素交换时,至少有一个元素移动,因此N个元素进行排序,就会移动 1--N 次,在所有依靠移动元素来排序的算法中,选择排序是比较优秀的一种

    选择排序时间复杂度与稳定性:

    最优时间复杂度: O(n2)

    最坏时间复杂度:O(n2)

    算法稳定性 :不稳定(考虑每次升序选择最大的时候)

    #             if alist[j] < alist[min_index]:
    #                 min_index = j
    #
    #         # 判断min_index索引是否相同,不相同,做数值交换
    #         if i != min_index:
    #             alist[i],alist[min_index] = alist[min_index],alist[i]
    #
    #
    # if __name__ == '__main__':
    #     alist = [12,34,56,78,90,87,65,43,21]
    #     # alist = [1,2,3,4,5,6,7,8,9]
    #     select_sort(alist)
    #     print(alist)
    
    # O(n^2)
    # 不稳定
    
    
    def select_sort(alist):
        """选择排序"""
        n = len(alist)
        for i in range(n - 1):
            min_index = i  # 最小值位置索引、下标
            for j in range(i+1, n):
                if  alist[j] < alist[min_index]:
                    min_index = j
            # 判断min_index ,如果和初始值不相同,作数值交换
            if min_index != i:
                alist[i], alist[min_index] = alist[min_index],alist[i]
    
    
    if __name__ == '__main__':
        alist = [8,10,15,30,25,90,66,2,999]
        select_sort(alist)
        print(alist)

     这是一些算法的时间复杂度与稳定性

        

    时间复杂度,空间复杂度

     

        接下来就要来说说时间复杂度与空间复杂度: 时间复杂度就是假如你 泡茶,从开始泡,到你喝完茶,一共用了多长时间,你中间要执行很多步骤,取茶叶,烧水,上厕所,接电话,这些都是要花时间的,

    在算法中,时间复杂度分为  O(1)最快 , O(nn)最慢,

    O(1) < O(logn) <O(n)<O(n2)<O(n3)<O(2n) <O(nn)    一般游览器的速度都在O(n),做我们这一行,要注意客户体验,如果你程序的运行特别慢,估计别人来一次,以后再也不会来了      

    下面给大家找了张如何计算 时间复杂度的图片:

     

        空间复杂度(space complexity) ,执行时所需要占的储存空间,记做 s(n)=O(f(n)),其中n是为算法的大小, 空间复杂度 绝对是效率的杀手,曾经看过一遍用插入算法的代码,来解释空间复杂度的,

    觉得特别厉害,我就比较low了,只能给大家简单的总结一下我遇到的空间复杂度了,

      一般来说,算法的空间复杂度值得是辅助空间,比如:一组数字,时间复杂度O(n),二维数组a[n][m]   :那么他的空间复杂度就是O(n*m)     ,因为变量的内存是自动分配的,第一个的定义是循环里面的,所以是n*O(1)   ,如果第二个循环在外边,那么就是1*O(1)     ,这里也只是一个了解性的东西,如果你的工作中很少用到,那么没有必要深究,因为用的真的很少

    优化算法

     

    这边带来了代码,你们在复制下来了python上运行一下,看一下用的时间与不同, 自然就懂了,

    这是未优化的算法  

     

    ''
    已知有a,b,c三个数,都是0-1000之内的数,
    且: a+b+c=1000 而且 a**2+b**2=c**2  ,求a,b,c一共有多少种组合
    '''
    # 在这里加一个时间模块,待会好计算出结果
    import time
    # 记录开头时间
    start_time=time.time()
    # 把a,b,c循环出来
    for  a in range(1001):
        for b in range(1001):
            for c in range(100):
                #  判断他  主公式  第一次,并未优化
                if a+b+c==1000 and a**2 + b**2 == c**2 :
                    # 打印
                    print("a=" ,a)
                    print("b=" ,b)
                    print("c=" ,c)
                else:
                    pass
    stop_time = time.time()
    print('一共耗时: %f'%(stop_time-start_time))
    # 一共耗时 156.875001秒

     

    这是第一次优化

    import time
    # 记录开头时间
    start_time=time.time()
    # 把a,b,c循环出来
    for  a in range(1001):
        # 这里改成1001-a之后,他就不用再循环b了
        for b in range(1001-a):
            for c in range(100):
                #  判断他  主公式  第二次,优化了b,
                if a+b+c==1000 and a**2 + b**2 == c**2 :
                    print("a=" ,a)
                    print("b=" ,b)
                    print("c=" ,c)
                else:
                    pass
    stop_time = time.time()
    print('一共耗时: %f'%(stop_time-start_time))
    # 一共耗时 50.557070秒

    最后一次优化

    import time
    # 记录开头时间
    start_time=time.time()
    # 把a,b,c循环出来
    for  a in range(1001):
        for b in range(1001-a):
                c=1000 - a - b
                #  判断他  主公式  第三次,优化了b和c
                if a+b+c==1000 and a**2 + b**2 == c**2 :
                    print("a=" ,a)
                    print("b=" ,b)
                    print("c=" ,c)
                else:
                    pass
    stop_time = time.time()
    print('一共耗时: %f'%(stop_time-start_time))
    # 一共耗时 2.551449秒

    从156秒优化到l2秒,    基本运算总数 * 基本运算耗时  = 运算时间    这之间的耗时和你的机器有着很大的关系

    今天是12月30日,明天就要跨年了,祝大家2019年事业有成,工资直线上升,早日脱单,

     

  • 相关阅读:
    熟练使用有棱有角的内存
    计算机进行小数运算时出错的原因
    数据是用二进制数表示的
    代码之外的功夫
    运行库实现
    系统调用与API
    运行库
    内存
    Windows下的动态链接
    Sharding-JDBC 实现垂直分库水平分表
  • 原文地址:https://www.cnblogs.com/lowbi/p/10164308.html
Copyright © 2011-2022 走看看