zoukankan      html  css  js  c++  java
  • 算法

    冒泡排序 O(n2)

    思想

    重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小(大)的元素会经由交换慢慢"浮"到数列的顶端。

    图示

    代码

    def bubbleSort(arr):
        n = len(arr)
     
        # 遍历所有数组元素
        for i in range(n):
            # 这里的 -1 很精髓,刚好循环到倒数第二项,倒数第二项这一轮的时候会跟最后一项做比较,不需要再多走最后一遍了,没有意义了
            # 不一定要 n-i-1 或者 n-i,哪怕是n都行,这样就实打实的循环了n^2次了而已,也是能正常排序的,n-i-1或者n-i的目的是为了优化而已
            for j in range(0, n-i-1):
                if arr[j] > arr[j+1] :
                    arr[j], arr[j+1] = arr[j+1], arr[j]
     
    arr = [64, 34, 25, 12, 22, 11, 90]
     
    bubbleSort(arr)
     
    print ("排序后的数组:")
    for i in range(len(arr)):
        print ("%d" %arr[i]),

       

    选择排序 O(n2)

    思想

    遍历无序列表,从中选出最小的元素,依次添加到新的列表中。

    首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

    实操

    实际操作的时候,并不是真的创建一个新的列表用来有序的存放数据,因为那样会造成额外的空间消耗,空间复杂度加大,所以其实一般都是用一个双层循环做遍历,在列表本地操作。

    代码

    """
    外层循环从0~length,内层循环从i+1~length
    比较两个数的大小,如果后面的数比前面的小,则互换位置
    """
    
    A = [64, 25, 12, 22, 11] 
      
    for i in range(len(A)): 
        # 定义一个变量,用来存最小元素的下标,默认从i开始
        min_idx = i 
        for j in range(i+1, len(A)): 
            # 从第i+1处开始,跟原来最小数比较
            if A[min_idx] > A[j]: 
                # 如果当前j的元素比原来的最小数更小,则将当前元素的下标给到min_idx
                min_idx = j 
         # 将找出来的最小数和第i个位置的数进行交换
        A[i], A[min_idx] = A[min_idx], A[i] 
      
    print ("排序后的数组:") 
    for i in range(len(A)): 
        print("%d" %A[i]),        

    插入排序 O(n2)

    思想

    通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 

    从第二位数字开始,每一个数字都试图跟它前一个数字进行比较并做交换,重复该动作,直到前一个数字不存在或者小于等于当前数字时为止。

    实操

    图示难以理解,这里有视频地址:https://v.qq.com/x/page/p05308yhnyp.html

    代码

    def insertionSort(arr): 
        for i in range(1, len(arr)):
            j = i - 1
            while j >= 0 and arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                j -= 1
      
      
    arr = [12, 11, 13, 5, 6] 
    insertionSort(arr) 
    print ("排序后的数组:") 
    for i in range(len(arr)): 
        print ("%d" %arr[i])

    快速排序 O(n*log2n)

    思想

    快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。

    步骤为:

    • 挑选基准值:从数列中挑出一个元素,称为"基准"(pivot);
    • 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
    • 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。

    递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。

    选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。

    图示

    代码

    def partition(arr,low,high): 
        i = ( low-1 )         # 最小元素索引
        pivot = arr[high]     
      
        for j in range(low , high): 
      
            # 当前元素小于或等于 pivot 
            if   arr[j] <= pivot: 
              
                i = i+1 
                arr[i],arr[j] = arr[j],arr[i] 
      
        arr[i+1],arr[high] = arr[high],arr[i+1] 
        return ( i+1 ) 
      
     
    # arr[] --> 排序数组
    # low  --> 起始索引
    # high  --> 结束索引
      
    # 快速排序函数
    def quickSort(arr,low,high): 
        if low < high: 
      
            pi = partition(arr,low,high) 
      
            quickSort(arr, low, pi-1) 
            quickSort(arr, pi+1, high) 
      
    arr = [10, 7, 8, 9, 1, 5] 
    n = len(arr) 
    quickSort(arr,0,n-1) 
    print ("排序后的数组:") 
    for i in range(n): 
        print ("%d" %arr[i]),

    归并排序

    堆排序

    希尔排序

  • 相关阅读:
    如何在CentOS 7中安装最新Git(源码安装)
    centos7安装Lua
    syslog-ng 学习
    syslog-ng内容讲解
    java框架篇---spring IOC 实现原理
    java 过滤器filter使用案例
    jsp-TagLib标签库
    阿里服务器+Centos7.4+Tomcat+JDK部署
    IntelliJ IDEA上创建maven Spring MVC项目
    ServiceStack.Redis之IRedisClient
  • 原文地址:https://www.cnblogs.com/hf8051/p/11442134.html
Copyright © 2011-2022 走看看