Python

来源:互联网 发布:魅族换windows系统 编辑:程序博客网 时间:2024/06/05 19:16

总结一下几种常见的排序算法


先做一个整体比较:

排序法 平均时间 最差情形 稳定度 额外空间 备注 冒泡 O(n2) O(n2) O(1) n小时较好 交换 O(n2) O(n2) O(1) n小时较好 选择 O(n2) O(n2) 不稳定 O(1) n小时较好 插入 O(n2) O(n2) 稳定 O(1) 大部分已排序时较好 基数 O(logRB) O(logRB) 稳定 O(n) B(0-9)R(个十百) 希尔 O(nlogn) O(ns)1<s<2 不稳定 O(1) s是所选分组 快速 O(nlogn) O(n2) 不稳定 O(nlogn) n大时较好 归并 O(nlogn) O(nlogn) 稳定 O(1) n大时较好 堆 O(nlogn) O(nlogn) 不稳定 O(1) n大时较好

本次主要以python3.X来介绍下选择,插入,希尔,快速,归并,堆排序。

  • 选择排序

    选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

    代码如下:

    import sys  def select_sort(a):      ''''' 选择排序      每一趟从待排序的数据元素中选出最小(或最大)的一个元素,     顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。     选择排序是不稳定的排序方法。     '''      a_len=len(a)      for i in range(a_len):#在0-n-1上依次选择相应大小的元素           min_index = i#记录最小元素的下标           for j in range(i+1, a_len):#查找最小值              if(a[j]<a[min_index]):                  min_index=j          if min_index != i:#找到最小元素进行交换              a[i],a[min_index] = a[min_index],a[i]  if __name__ == '__main__':      A = [10, -3, 5, 7, 1, 3, 7]        print('Before sort:'.format(A))        select_sort(A)        print('After sort:'.format(A))
    • 插入排序
    import sys  def insert_sort(a):      ''''' 插入排序     有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,     但要求插入后此数据序列仍然有序。刚开始 一个元素显然有序,然后插入一     个元素到适当位置,然后再插入第三个元素,依次类推     '''      a_len = len(a)      if a_len = 0 and a[j] > key:              a[j+1] = a[j]              j-=1          a[j+1] = key      return a  if __name__ == '__main__':      nums = [10,8,4,-1,2,6,7,3]      print('nums is:'.format(nums))      insert_sort(nums)      print('insert sort:'.format(nums))
  • 希尔排序

    import sys  def shell_sort(a):      ''''' shell排序      '''      a_len=len(a)      gap=a_len/2#增量      while gap>0:          for i in range(a_len):#对同一个组进行选择排序              m=i              j=i+1              while j<a_len:                  if a[j]<a[m]:                      m=j                  j+=gap#j增加gap              if m!=i:                  a[m],a[i]=a[i],a[m]          gap/=2  if __name__ == '__main__':      A = [10, -3, 5, 7, 1, 3, 7]        print('Before sort:'.format(A))        shell_sort(A)        print('After sort:'.format(A))
  • 快速排序

    ''''' 划分 使满足 以A[r]为基准对数组进行一个划分,比A[r]小的放在左边,    比A[r]大的放在右边 快速排序的分治partition过程有两种方法, 一种是上面所述的两个指针索引一前一后逐步向后扫描的方法, 另一种方法是两个指针从首位向中间扫描的方法。 '''  #p,r 是数组A的下标  def partition1(A, p ,r):      '''''       方法一,两个指针索引一前一后逐步向后扫描的方法     '''      x = A[r]      i = p-1      j = p      while j < r:          if A[j] < x:              i +=1              A[i], A[j] = A[j], A[i]          j += 1      A[i+1], A[r] = A[r], A[i+1]      return i+1  def partition2(A, p, r):      '''''     两个指针从首尾向中间扫描的方法     '''      i = p      j = r      x = A[p]      while i = x and i < j:              j -=1          A[i] = A[j]          while A[i]<=x and i < j:              i +=1          A[j] = A[i]      A[i] = x      return i  # quick sort  def quick_sort(A, p, r):      '''''         快速排序的最差时间复杂度为O(n2),平时时间复杂度为O(nlgn)     '''      if p < r:          q = partition2(A, p, r)          quick_sort(A, p, q-1)          quick_sort(A, q+1, r)  if __name__ == '__main__':      A = [5,-4,6,3,7,11,1,2]      print('Before sort:'.format(A))      quick_sort(A, 0, 7)      print('After sort:'.format(A))
  • 归并排序

    import sys  def merge(nums, first, middle, last):      ''''' merge '''      # 切片边界,左闭右开并且是了0为开始      lnums = nums[first:middle+1]       rnums = nums[middle+1:last+1]      lnums.append(sys.maxint)      rnums.append(sys.maxint)      l = 0      r = 0      for i in range(first, last+1):          if lnums[l] < rnums[r]:              nums[i] = lnums[l]              l+=1          else:              nums[i] = rnums[r]              r+=1  def merge_sort(nums, first, last):      ''''' merge sort     merge_sort函数中传递的是下标,不是元素个数     '''      if first < last:          middle = (first + last)/2          merge_sort(nums, first, middle)          merge_sort(nums, middle+1, last)          merge(nums, first, middle,last)  if __name__ == '__main__':      nums = [10,8,4,-1,2,6,7,3]      print('nums is:'.format(nums))    merge_sort(nums, 0, 7)      print('merge sort:'.format(nums))
  • 堆排序

    # 数组编号从 0开始  def left(i):      return 2*i +1  def right(i):      return 2*i+2  #保持最大堆性质 使以i为根的子树成为最大堆  def max_heapify(A, i, heap_size):      if heap_size <= 0:          return       l = left(i)      r = right(i)      largest = i # 选出子节点中较大的节点      if l  A[largest]:          largest = l      if r  A[largest]:          largest = r      if i != largest :#说明当前节点不是最大的,下移          A[i], A[largest] = A[largest], A[i] #交换          max_heapify(A, largest, heap_size)#继续追踪下移的点      #print A  # 建堆    def bulid_max_heap(A):      heap_size = len(A)      if heap_size >1:          node = heap_size/2 -1          while node >= 0:             max_heapify(A, node, heap_size)             node -=1  # 堆排序 下标从0开始  def heap_sort(A):      bulid_max_heap(A)      heap_size = len(A)      i = heap_size - 1       while i > 0 :          A[0],A[i] = A[i], A[0] # 堆中的最大值存入数组适当的位置,并且进行交换          heap_size -=1 # heap 大小 递减 1          i -= 1 # 存放堆中最大值的下标递减 1          max_heapify(A, 0, heap_size)  if __name__ == '__main__' :      A = [10, -3, 5, 7, 1, 3, 7]      print('Before sort:'.format(A))      heap_sort(A)      print('After sort:'.format(A))
原创粉丝点击