• python数据结构与算法——快速排序


    快速排序通过不断将数列分段,使得较小的数在左边的序列,较大的数在右边的序列,不断重复此过程实现排序效果。通过设置两个哨兵不断的找两个序列的较小数,较大数,并把左右的数据互换,实现对数据从粗到细的排序。

    算法如下:

    快速排序排序 从大到小

    1. 先让从最右边的哨兵开始出发往左移动,直到找到一个小于 A[base] 的数,或者碰到左边的哨兵
    2. 再从最左边的哨兵开始出发往右移动,直到找到一个大于 A[base] 的数,或者碰到右边的哨兵
    3. 如果没有相遇,这将两个哨兵所在的元素交换,使得较小的元素分到了左边,较大的元素分到了右边
    4. 当两个哨兵相遇,则结束循环,把序列分成两个部分,即 低端序列(都是较小元素) 和 高端序列(都是较大元素)
    5. 递归,分别对 低端序列 和 高端序列 进行同样的过程

    贴代码:

     1 def quicksort_rec(A,lft=None,rgt=None):
     2     
     3     if lft == None or rgt == None:
     4         lft, rgt = 0, len(A)-1
     5     if lft >= rgt:   
     6         return
     7 
     8     i = lft                                 # 序列最左边的哨兵
     9     j = rgt                                 # 序列最右边的哨兵
    10     base = lft                              # 基准数的索引
    11     while i != j:               
    12         while A[j] >= A[base] and i < j:    # 先从右往左找
    13             j -= 1
    14         while A[i] <= A[base] and i < j:
    15             i += 1
    16         if i < j:                           # 没有相遇:交换
    17             A[i], A[j] = A[j], A[i]
    18     
    19     A[base], A[i] = A[i], A[base]           # 基准数归位, 索引 i 为序列正中
    20     quicksort_rec(A, lft, i-1)              # 递归处理左边序列
    21     quicksort_rec(A, i+1, rgt)              # 递归处理右边序列

    很短对不对,下面是运行结果:

        A = [6,1,2,7,9,3,4,2,5,10,8,1]
        quicksort_rec(A)
        print A
    
    >>> [1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    另一种更简洁的实现方式:

     1 # 分离数列seq为低端序列和高端序列
     2 def partition(seq):
     3     pi, seq = seq[0], seq[1:]           # 选择数列中第0个数据为基准元素
     4     lo = [x for x in seq if x <= pi]    # 选出seq中较小元素
     5     hi = [x for x in seq if x > pi]     # 选出seq中较大元素
     6     return lo,pi,hi
     7 
     8 
     9 # 快速排序法
    10 def quicksort(seq):
    11     if len(seq)<=1: return seq
    12     lo, pi, hi = partition(seq)
    13     return quicksort(lo) + [pi] + quicksort(hi)
    14 
    15 # 测试
    16 seq = [1,2,4,6,3,7,5,9,0,5,7]
    17 print  quicksort(seq) 
    18 
    19 >>> [0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 9]

    利用上面的函数partition,可以使用二分法查找第k个最小的元素(不排序)

    1 # 选择数组中第k小元素
    2 def select(seq, k):
    3     lo, pi, hi = partition(seq)         # [<= pi], pi, [> pi]
    4     m = len(lo)
    5     if m == k:  return pi               # 找到第k最小值
    6     elif m < k:
    7         return select(hi,k-m-1)         
    8     else:
    9         return select(lo,k)

    调用方法:

    # 原数组:seq = [1,2,4,6,3,7,5,9,0,5,7]
    # 排序后:[0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 9]
    print select(seq,6)
    
    >>> 5
  • 相关阅读:
    人事面试13
    人事面试测试篇1
    人事面试16
    人事面试15
    人事面试测试篇3
    人事面试测试篇2
    人事面试14
    Oracle Compile 编译 无效对象
    Oracle 移动数据文件的操作方法
    Oracle 9i 从9.2.0.1升级到 9.2.0.6 步骤
  • 原文地址:https://www.cnblogs.com/hanahimi/p/4692324.html
Copyright © 2020-2023  润新知