数据结构和算法----排序算法day2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bquau/article/details/89030778
  • 归并排序
    • 原理:
  • 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。 若将两个有序表合并成一个有序表,称为二路归并。(以上是官方解释)
  •            个人理解就是归并将一组数据用二分法将其分割成无数个小数列,然后再把小数列两两排序合并
    • 代码:
  • #encoding:utf-8
  • #数组合并排序
  • def marge(left,right):
  •     #定义两个指针,和存储数组
  •     c = []
  •     a = b = 0
  •     #比较左右子数组指针下的数字大小,并添加到存储数组
  •     while a < len(left) and b < len(right):
  •         if left[a] > right[b]:
  •             c.append(right[b])
  •             b += 1
  •         else:
  •             c.append(left[a])
  •             a += 1
  •     c += left[a:] + right[b:]
  •     return c
  •     #将左子数组或右子数组剩余数据存入存储数组
  •     #返回存储数组
  • #递归分割数组
  • def marge_sort(lis):
  •     list_len = len(lis)
  •     #如果lis长度为1则返回list
  •     if list_len <= 1:
  •         return lis
  •     #获取list分割点的下标
  •     middler = list_len // 2
  •     #将分割后的数组继续分割直到长度为一为止
  •     left = marge_sort(lis[:middler])
  •     right = marge_sort(lis[middler:])
  •     #将分割后的数组排序合并
  •         return marge(left,right)
    • 分析:
  • 空间复杂度:因为每次合并都需要申请一个存储空间,合并之后释放掉所以,所以临时内存空间不会超过数列的元素个数也就是n,所以空间复杂度为O(n)
  • 时间复杂度:递归的时间复杂度用公式来看
  •             T(n) = 2 * T(n/2) + n  
  •             T(n):时间复杂度
  •             2*T(n/2):二分的时间复杂度
  •             n:合并的时间复杂度
  •             最后算得T(n) = O(nlogn)
  •                      稳定性:如果左右数组值相等,那么先存左数组数据,就能保证其稳定性。所以归并排序是稳定得排序算法
  • 快速排序
    • 原理:
  • 先从数列中取出一个数作为基准数。
  • 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  • 再对左右区间重复第二步,直到各区间只有一个数。
    • 代码:
  • def quick_sort(array, l, r):
    
        #如果左右边界相等则返回
    
        if r > l:
    
            #定义分区点位置得指针
    
            i = l
    
            #定义分区点
    
            key = array[r]
    
            #遍历数组将小于分区点得数据都放入分区点左面
    
            for j in range(l,r):
    
                if key > array[j]:
    
                    array[i],array[j] = array[j],array[i]
    
                    i += 1
    
            #将分区点放入指针指定得位置
    
            array[r],array[i] = array[i],array[r]
    
            #排序结束将分区点左右子数组进行递归排序
    
            quick_sort(array,l,i-1)
    
            quick_sort(array,i+1,r)
  •  
  • python实现一行代码的快排:
  • quick_sort = lambda array: array if len(array) <= 1 else  quick_sort([item for item in array[1:] if item <= array[0]]) + [array[0]] +  quick_sort([item for item in array[1:] if item > array[0]])
  • 拆分理解一下
  • # 这个不难理解如果数组长度小于等于一表达式结果就为array本身
    
    quick_sort = lambda array: array if len(array) <= 1 else \
    
    # 取出array中小于分区点的所有元素,放在分区点左面
    
        quick_sort([item for item in array[1:] if item <= array[0]]) + \
    
    #分区点
    
        [array[0]] + \
    
    #取出array中大于分区点的所有元素,放到分区点右面
    
        quick_sort([item for item in array[1:] if item > array[0]])
  • 仔细看不难,但是要是自己写需要费点心神
    • 分析:
  • 空间复杂度:原地排序O(1)
  • 时间复杂度:同样写出公式分析
  •          T(n) = 2 * T(n/2) + n与归并排序相同,所以时间复杂度同为O(nlogn)
  • 稳定性:不稳定

猜你喜欢

转载自blog.csdn.net/bquau/article/details/89030778