• Python实现常用查找与排序算法


     

    查找算法

    二分查找

    import doctest
    
    def binary_search(alist, item):
        """
        >>> alist=[1,3,4,7,11,18,29]
        >>> binary_search(alist,1)
        0
        >>> binary_search(alist,7)
        3
        >>> binary_search(alist,18)
        5
        >>> binary_search(alist,31)
    
        """
    
        binary_index = int(len(alist)/2)
        if alist == []:
            return None
        elif alist[binary_index] > item:
            return binary_search(alist[:binary_index], item)
        elif alist[binary_index] < item:
            result = binary_search(alist[binary_index + 1:], item)
            return  None if result is None else result + binary_index + 1
        elif alist[binary_index] == item:
            return binary_index
    
    if __name__ == "__main__":
        doctest.testmod(verbose=True)

    排序算法 

    选择排序

    原理:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。

    稳定性:不稳定

    最差时间复杂度:O(n^2)

    平均时间复杂度:O(n^2)

    import doctest
    def select_sort(alist, reverse=False): """ >>> alist = [1,7,4,8,6,9,2,5,3] >>> select_sort(alist) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> select_sort(alist, reverse=True) [9, 8, 7, 6, 5, 4, 3, 2, 1] """ alist = alist[:] def select_sort_(alist, reverse): if alist == []: return [] item = max(alist) if reverse else min(alist) alist.remove(item) return [item] + select_sort_(alist,reverse) return select_sort_(alist, reverse) if __name__ == "__main__": doctest.testmod(verbose=True)

    冒泡排序 

    原理:依次比较相邻两个元素大小,交换两元素位置使之满足递增或递减关系,完成一次从序列头到序列尾部的过程称为一次冒泡,一次冒泡会产生最大或最小值于队列尾部,下一次冒泡序列长度减1,序列尾部的有序序列长度加1

    稳定性:稳定

    最差时间复杂度:O(n^2)

    平均时间复杂度:O(n^2)

    import doctest

    def bubbing_sort(alist, reverse=False): """ >>> alist = [1,7,4,8,6,9,2,5,3] >>> select_sort(alist) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> select_sort(alist, reverse=True) [9, 8, 7, 6, 5, 4, 3, 2, 1] """ def swap(alist, index1, index2): temp = alist[index1] alist[index1] = alist[index2] alist[index2] = temp pass alist = alist[:] for cnt in range(len(alist) - 1): for index1 in range(len(alist) - 1 - cnt): index2 = index1 + 1 if (alist[index1] > alist[index2] and reverse == False) or (alist[index1] < alist[index2] and reverse == True): swap(alist, index1, index2) return alist if __name__ == "__main__": doctest.testmod(verbose=True)

    插入排序

    原理:将序列元素依次插入到序列首部的有序序列中,即每个元素执行一次有序插入操作

    稳定性:稳定

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

    平均时间复杂度:O(n2)

    import doctest
    
    def insert_sort(alist, reverse=False):
        """
        >>> alist = [1,7,4,8,6,9,2,5,3]
        >>> insert_sort(alist)
        [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
        >>> insert_sort(alist, reverse=True)
        [9, 8, 7, 6, 5, 4, 3, 2, 1]
    
        """
        result = alist[:1]
        for val in alist[1:]:
            for sort_val in result:
                if (val < sort_val and reverse == False) or (val > sort_val and reverse == True):
                    result.insert(result.index(sort_val), val)
                    break
            else:
                result.insert(len(result), val)
        return result
    
    if __name__ == "__main__":
        doctest.testmod(verbose=True)

    快速排序 

    原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

    性质:不稳定

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

    平均时间复杂度:O(nlogn)

    import doctest
    import copy
    import random
    
    def quick_sort(alist, reverse=False):
        """
        >>> alist = [1,7,4,8,6,9,2,5,3]
        >>> quick_sort(alist)
        [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
        >>> quick_sort(alist, reverse=True)
        [9, 8, 7, 6, 5, 4, 3, 2, 1]
    
        """
        alist = copy.copy(alist)
        def quick_sort_(alist, reverse):
            if alist == []:
                return []
    
            dichotomy_index = random.randint(0, len(alist) - 1)
            dichotomy_val = alist[dichotomy_index]
            alist.pop(dichotomy_index)
            left_list = []
            right_list = []
            for val in alist:
                if (val >= dichotomy_val and reverse == True) or (val < dichotomy_val and reverse == False):
                    left_list += [val]
                else:
                    right_list += [val]
    
            return quick_sort_(left_list, reverse) + [dichotomy_val] + quick_sort_(right_list, reverse)
        return quick_sort_(alist, reverse)
    
    if __name__ == "__main__":
        doctest.testmod(verbose=True)

    归并排序 

    原理:将序列通过递归二分拆分到不可分,不可分的序列可以认为是有序序列,然后将两个有序序列合并为一个有序序列,直到整个序列变为一个有序序列

    稳定性:稳定

    最差时间复杂度:O(nlogn)

    平均时间复杂度:O(nlogn)

    import doctest
    
    def merger_sort(alist, reverse=False):
        """
        >>> alist = [1,7,4,8,6,9,2,5,3]
        >>> merger_sort(alist)
        [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
        >>> merger_sort(alist, reverse=True)
        [9, 8, 7, 6, 5, 4, 3, 2, 1]
    
        """
        
        def merger(a, b):
            result = []
            for n in range(len(a) + len(b)):
                if a == []:
                    return result + b
                elif b == []:
                    return result + a
                elif (a[0] < b[0] and reverse == False) or (a[0] > b[0] and reverse == True):
                    result += [a.pop(0)]
                else:
                    result += [b.pop(0)]
            return result
    
        def merger_sort_(alist):        
            contre_index = int(len(alist)/2)
            left_list = alist[:contre_index]
            right_list = alist[contre_index:]
            if len(left_list) >= 2:
                left_list = merger_sort_(left_list)
            if len(right_list) >= 2:
                right_list = merger_sort_(right_list)
            return merger(left_list,right_list)
    
        return merger_sort_(alist)
    
    if __name__ == "__main__":
        doctest.testmod(verbose=True)

    堆排序

    原理:堆排序也是选择排序的一种,他是利用完全二叉树的结构,从而构造出最大堆或最小堆,将堆顶元素替换到堆尾,如此反复,从而构造出有序序列

    稳定性:不稳定

    最差时间复杂度:O(nlogn)

    平均时间复杂度:O(nlogn)

    import doctest
    
    def heap_sort(alist, reverse=False):
        """
        >>> alist = [1,7,4,8,6,9,2,5,3]
        >>> heap_sort(alist)
        [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
        >>> heap_sort(alist, reverse=True)
        [9, 8, 7, 6, 5, 4, 3, 2, 1]
    
        """
        
        A = alist[:]
        def perc_down(A, i, N):
            Ai = A[i]
            def perc_down_(A, i, N):
                temp = A[i]
                child = i * 2 + 1
    
                if child  < N - 1 and ((A[child] < A[child + 1]  and reverse == False) or (A[child] >= A[child + 1] and reverse == True)):
                    child += 1
                if child < N and ((Ai < A[child] and reverse == False) or (Ai >= A[child] and reverse == True)):
                    A[i] = perc_down_(A, child, N)
                else:
                    A[i] = Ai
                
                return temp
            perc_down_(A, i, N)
    
        def swap(A, a, b):
            temp = A[a]
            A[a] = A[b]
            A[b] = temp
    
        for n in list(range(int(len(A)/2)))[::-1]:
            perc_down(A, n, len(A))
    
        for n in list(range(len(A)))[::-1]:
            swap(A, 0, n)
            perc_down(A, 0, n)
    
    
        return A
    
    if __name__ == "__main__":
        doctest.testmod(verbose=True)
  • 相关阅读:
    unit3d 4.6 document open solution
    Unity3dBug
    linq to xml
    A const field of a reference type other than string can only be initialized with null Error [duplicate]
    Redis数据类型
    redis快照与AOF
    redis实现高并发下的抢购/秒杀功能
    xss攻击怎么防止
    四种常见的索引类型
    什么是sql 注入及如何预防 sql 注入
  • 原文地址:https://www.cnblogs.com/plyonfly/p/11420955.html
Copyright © 2020-2023  润新知