zoukankan      html  css  js  c++  java
  • 八大经典排序算法——Python(PS:二分查找)

    一、冒泡排序(交换排序)  

    # BubbleSort - Using bubble sort method for a chaotic sequence in ascending order, request the first to come up to the minimum.
    
    class Solution(object):
        def bubbleSort(self, nums):
            size = len(nums)
            for i in range(0, size - 1):
                j = size - 1
                while j > 0:
                    if nums[j] < nums[j - 1]:
                        nums[j - 1], nums[j] = nums[j], nums[j - 1]
                    j -= 1
            return nums
    
    if __name__ == "__main__":
        s = Solution()
        print(s.bubbleSort(nums=[35, 80, 21, 54, 11, 45, 92, 39]))

    二、选择排序  

    # SelectionSort - Using the selection method for a chaotic sequence in ascending order.
    
    def SelectSort(a):
        for i in range(0, len(a) - 1):    # 外层循环 找i次最小值
            min = i               # 此处记录最小值位置,不能改变数列中的数值
            for j in range(i + 1, len(a) - 1):    # 内层循环 找到最小值
                if a[j] < a[min]:
                    min = j      # 变量 j 更新并记录最小值位置
            p = a[i]      # 变量 p 储存最小值(把第一个最小值放入的位置的那个原有值记录在temp里)
            a[i] = a[min]   # 将最小值覆盖到那个位置里
            a[min] = p    # 再把p里保存的最小值更新到未排数列的第一个
        return a
    
    print(SelectSort(a=[35, 80, 21, 54, 11, 45, 92, 39]))

    三、插入排序  

    # InsertSort - Using insertion sort method for a chaotic sequence in ascending order.
    
    class Solution(object):
        def insertionSort(self, nums):
            size = len(nums)
            for i in range(1, size):
                if nums[i] < nums[i - 1]:
                    temp = nums[i]
                    j = i        # 记下未排序第一个的位置
                    while j > 0 and temp < nums[j - 1]:
                        nums[j] = nums[j - 1]
                        j -= 1
                    nums[j] = temp   # 插入待排序的数字
            return nums
    
    if __name__ == "__main__":
        s = Solution()
        print(s.insertionSort(nums=[35, 80, 21, 54, 11, 45, 92, 39]))

    四、希尔排序——(插入排序的改进)

    #!/usr/bin/env python
    # coding:utf-8
    
    def shellSort(nums):
        # 设定步长
        step = len(nums)/2
        while step > 0:
            for i in range(step, len(nums)):
                # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置
                while i >= step and nums[i-step] > nums[i]:
                    nums[i], nums[i-step] = nums[i-step], nums[i]
                    i -= step
            step = step/2
        return nums
    
    if __name__ == '__main__':
        nums = [9,3,5,8,2,7,1]
        print shellSort(nums)

    五、快速排序——(冒泡排序的改进)

        过程:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序(递归实现)。

    一趟快速排序的算法是:

    1)设置两个变量low、high,排序开始的时候:low=0,high=len(a)-1;

    2)以第一个数组元素作为关键数据,赋值给key,即key=a[low];

    3)从j开始向前搜索,即由后开始向前搜索(high--),找到第一个小于key的值a[high],将a[high]和a[low]互换;

    4)从i开始向后搜索,即由前开始向后搜索(low++),找到第一个大于key的a[low],将a[low]和a[high]互换;

    5)重复第3、4步,直到low=high;

           (3,4步中,没找到符合条件的值,即3中a[high]不小于key,4中a[low]不大于key的时候改变high、low的值,使得high=high-1,low=low+1,直至找到为止。找到符合条件的值,

    进行交换的时候low, high指针位置不变。另外,low==high这一过程一定正好是low+或high-完成的时候,此时令循环结束)。

    # QuickSort - Using quick sort method for a chaotic sequence in ascending order.
    
    
    def partition(a, left, right):   # 定义分区函数,第一遍排序
        low = left
        high = right
        key = a[low]
        while low < high:
            while low < high and a[high] >= key:    # 因为基准 key 从左开始,所以第一遍从右开始遍历
                high -= 1
            a[low] = a[high]
            while low < high and a[low] <= key:
                low += 1
            a[high] = a[low]
            a[low] = key                       # 每一次循环结束记录一次基准 key 的位置,防止 key 值丢失
        return low
    
    def QuickSort(a, left, right):            # 定义递归函数
        if left < right:                      # !!!判断条件很重要,很容易忽略
            p = partition(a, left, right)
            QuickSort(a, left, p - 1)
            QuickSort(a, p + 1, right)
        return a
    
    a = [35, 80, 21, 54, 11, 45, 92, 39]
    print(QuickSort(a, 0, len(a) - 1))

    六、归并排序(递归)

    def merge(left,right):  
        result=[]  
        i,j=0,0  
        while i<len(left) and j<len(right):  
            if left[i]<=right[j]:  
                result.append(left[i])  
                i+=1  
            else:  
                result.append(right[j])  
                j+=1  
        result+=left[i:]  
        result+=right[j:]  
        return result  
    
    def mergesort(seq):  
        if len(seq)<=1:  
            return seq  
        mid=int(len(seq)/2)  
        left=mergesort(seq[:mid])  
        right=mergesort(seq[mid:])  
        return merge(left,right)
    
    if __name__=='__main__':  
        seq=[4,5,7,9,7,5,1,0,7,-2,3,-99,6]  
        print(mergesort(seq))

    七、堆排序—— (选择排序的改进)

    #coding: utf-8 
    #!/usr/bin/python   
    import random
    import math
    
    #随机生成0~100之间的数值
    def get_andomNumber(num):  
        lists=[]  
        i=0  
        while i<num:  
            lists.append(random.randint(0,100))  
            i+=1
        return lists
    
    
    # 调整堆
    def adjust_heap(lists, i, size):
        lchild = 2 * i + 1
        rchild = 2 * i + 2
        max = i
        if i < size / 2:
            if lchild < size and lists[lchild] > lists[max]:
                max = lchild
            if rchild < size and lists[rchild] > lists[max]:
                max = rchild
            if max != i:
                lists[max], lists[i] = lists[i], lists[max]
                adjust_heap(lists, max, size)
    
    # 创建堆
    def build_heap(lists, size):
        for i in range(0, (int(size/2)))[::-1]:
            adjust_heap(lists, i, size)
    
    # 堆排序
    def heap_sort(lists):
        size = len(lists)
        build_heap(lists, size)
        for i in range(0, size)[::-1]:
            lists[0], lists[i] = lists[i], lists[0]
            adjust_heap(lists, 0, i)
        return lists
    
    
    a = get_andomNumber(10)
    print("排序之前:%s" %a)
    
    b = heap_sort(a)
    
    print("排序之后:%s" %b)

    八、桶排序(bucket sort & bin sort)

    # BucketSort - Using the Bucket Sort method for a chaotic sequence in ascending order.
    
    def BucketSort(a):
        b = [0] * max(a)    #预先设定的列表,全部置零
        result = []
        for num in a:       #遍历成绩,相应得分位置+1
            b[num - 1] += 1      #a的值成为b的索引,此时标记b中不为空的位置
        for i in range(0, len(b)):   #遍历生成的列表
            for j in range(0, b[i]):
                result.append(i + 1)
        return result
    
    print(BucketSort(a=[35, 80, 21, 54, 11, 45, 92, 39]))

    PS:

    排序算法稳定性:

            假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

            稳定的排序算法:基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序

            不稳定的排序算法:堆排序、快速排序、希尔排序、直接选择排序

     排序算法复杂度:

                                              

    PS——二分查找(binary_search)

    def binary_search(a, key):
        if not a:
            return 0
        time = 0
        low = 0
        high = len(a) - 1
        while low <= high:
            time += 1
            mid = int((low + high) / 2)
            if a[mid] == key:
                print("times: %s" % time)
                return mid
            elif a[mid] > key:
                high = mid - 1
            else:
                low = mid + 1
        return False
    
    if __name__ == '__main__':
        LIST = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
        result = binary_search(LIST, 200)
        print(result)
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/llw1121/p/6838357.html
Copyright © 2011-2022 走看看