zoukankan      html  css  js  c++  java
  • [Python]7种基础排序算法-Python实现

    Basic 7 Algorithms in Python

    Bubble Sort(冒泡排序)

    Main Idea: use two loops to iterate data array, find the maximum, and throw it to the end.
    (两次循环,每次选大的放在后面,重复,直到没有数据)

    Feature: Stable O(n^2)

        def bubble_sort(arr):
            for i in range(len(arr)):
    	        for j in range(0, len(arr) - i - 1):
                    if arr[j] > arr[j + 1]:
                        arr[j], arr[j + 1] = arr[j + 1], arr[j]
            return arr
    

    Alternative: add a flag into outter loop, reducing the # of comparison.
    (通过在外循环设置标志位,可以减少比较的次数,但意义不大)

        def bubble_sort(arr):
            for i in range(len(arr)):
                flag = 0
                for j in range(0, len(arr) - i - 1):
                    if arr[j] >= arr[j + 1]:
                        flag += 1
                        arr[j], arr[j + 1] = arr[j + 1], arr[j]
                if flag == 0:
                    break
            return arr
    

    Test Code Link

    Selection Sort(选择排序)

    Main Idea: use two loops to iterate data array, find the minimum, and insert it at the beginning.
    (两次循环,每次选小的放在前面,重复,直到没有数据)

    Feature: Unstable O(n^2)

        def selection_sort(arr):
            for i in range(len(arr)):
                for j in range(i, len(arr)):
                    if arr[i] > arr[j]:
                        arr[i], arr[j] = arr[j], arr[i]
            return arr
    

    Alternative: store the current index, reducing the # of switching.
    (通过在外循环存储的索引, 减少数据交换的次数)

        def selection_sort(arr):
            for i in range(len(arr)):
                min_idx = i
                for j in range(i, len(arr)):
                    if arr[min_idx] > arr[j]:
                        min_idx = j
                if i != min_idx:
                    arr[i], arr[min_idx] = arr[min_idx], arr[i]
            return arr
    

    Test Code Link

    Insertion Sort(插入排序)

    Main Idea: use two loops to iterate data array simultaneously, insert a new data item into sorted results at an appropriate location. and push the rest data behind this location as a whole.
    (两次循环,将无序数据插入到已经有序的结果中,在插入位置,将后面的数据整体后移,重复,直到没有数据)

    Feature: Stable O(n^2)

        def insertion_sort(arr):
            for i in range(len(arr)):
                prev_idx = i - 1
                current = arr[i]
                while prev_idx >= 0 and arr[prev_idx] > current:
                    arr[prev_idx + 1] = arr[prev_idx]
                    prev_idx -= 1
                arr[prev_idx + 1] = current
            return arr
    

    Alternative1: use binary search to find the location where the new element should insert.
    (用二分查找,找到需要插入的位置)

        def insertion_sort(arr):
            for i in range(len(arr)):
                current = arr[i]
                low, high = 0, i - 1
                while low <= high:
                    mid = int((low + high) / 2)
                    if current < arr[mid]:
                        high = mid - 1
                    else:
                        low = mid + 1
                for j in range(i, low, -1):
                    arr[j] = arr[j - 1]
                arr[low] = current
            return arr
    

    Alternative2: use a descreasing number as a gap, to accelerate seaching process.
    (用一个递减的数值,作为间隔,每轮中,比较每个间隔对应的值,结合直接插入排序。 还有另外一个名字-希尔排序)

        def insertion_sort(arr):
            gap = len(arr) // 2
            while gap >= 1:
                for i in range(gap, len(arr)):
                    end_val = arr[i]
                    front_idx = i - gap
                    while front_idx >= 0 and arr[front_idx] > end_val:
                        arr[front_idx + gap] = arr[front_idx]
                        front_idx -= gap
                    arr[front_idx + gap] = end_val
                gap //= 2
            return arr
    

    Feature: Unstable O(nlogn)

    Test Code Link

    Merge Sort(归并排序)

    Main Idea: a classic sorting solution using divide-and-conquer. split data into pieces, and sort those small data and combine all of them.
    (递归地把当前序列平均分成两半, 分到只剩一个元素的时候, 停止切分开始进行两两排序,当解决完N个小问题之后,就可以把结果再拼装起来)

    Feature: Stable O(nlogn)

        def merge(left, right):
            res = []
            while left and right:
                min_val = left.pop(0) if left[0] < right[0] else right.pop(0)
                res.append(min_val)
            res += left if left else right
            return res
    
        def merge_sort(arr):
            if len(arr) <= 1:
                return arr
            mid = len(arr) // 2
            left = merge_sort(arr[:mid])
            right = merge_sort(arr[mid:])
            return merge(left, right)
    

    Alternative: instead, use a recursion method to write this algorithm, we can also use an iteration way.
    (除了使用递归方式去实现归并排序,也可以使用迭代的思路去实现)

        def merge(arr, low, mid, high):
            left = arr[low: mid]
            right = arr[mid: high]
            res = []
            while left and right:
                min_val = left.pop(0) if left[0] < right[0] else right.pop(0)
                res.append(min_val)
            res += left if left else right
            arr[low: high] = res
    
        def merge_sort(arr):
            sub_length = 1
            while sub_length < len(arr):
                low = 0
                while low < len(arr):
                    mid = low + sub_length
                    high = min(low + 2 * sub_length, len(arr))
                    if mid < high:
                        merge(arr, low, mid, high)
                    low += 2 * sub_length
                sub_length *= 2
            return arr
    

    Test Code Link1 | Test Code Link2

    Quick Sort(快速排序)

    Main Idea: another classic solution using divide-and-conquer. choose an item as pivot, split data into two part, one part is less than pivot, the rest will greater than pivot. continue doing this until no data.
    (通过设置枢轴的方式,将原始数据分成两个部分,将两个小部分排序并把结果最后合起来,重复切分,直到没有数据)

    Feature: Unstable O(nlogn)

        def quick_sort(arr, left, right):
            if left < right:
                pivot = arr[right]
                low, high = left, right
                while left< right:
                    while left < right and arr[left] < pivot:
                        left += 1
                    arr[right] = arr[left]
    
                    while left < right and arr[right] > pivot:
                        right -= 1
                    arr[left] = arr[right]
    
                arr[left] = pivot
                quick_sort(arr, low, left - 1)
                quick_sort(arr, left + 1, high)
            return arr
    

    Alternative1: the most easy way to do quick sorting.
    (我认为是最容易理解的一种实现方式)

        def quick_sort(arr):
            if arr:
                pivot = arr[0]
                less = [x for x in arr if x < pivot]
                great = [x for x in arr if x > pivot]
                return quick_sort(less) + [pivot] + quick_sort(great)
            else:
                return []
    

    Alternative2: 1. return the index of pivot. 2. split the data.
    (设置一个函数返回枢轴的位置,以此位置切分原始数据,一直迭代下去)

        def quick_sort(arr, left, right):
            if left < right:
                pivot_idx = split(arr, left, right)
                quick_sort(arr, left, pivot_idx - 1)
                quick_sort(arr, pivot_idx + 1, right)
            return arr
    
        def split(arr, left, right):
            pivot = arr[right]
            i = left - 1
            for j in range(left, right):
                if arr[j] <= pivot:
                    i += 1
                    arr[i], arr[j] = arr[j], arr[i]
            arr[i + 1], arr[right] = pivot, arr[i + 1]
            return i + 1
    

    Test Code Link1 | Test Code Link2

    Counting Sort(计数排序)

    Main Idea: convert data item into key-value pair, the iterate the keys.
    (将输入的数据值转化为键存储在额外开辟的桶空间中,然后遍历生成的桶,从小到大依次拿出来就是结果)

    Feature: Stable O(n + k)

        def bucket_sort(arr):
            buckets = [0] * ((max(arr) - min(arr)) + 1)
            for i in range(len(arr)):
                buckets[arr[i] - min(arr)] += 1
            res = []
            for i in range(len(buckets)):
                if buckets[i] != 0:
                    res += [i + min(arr)] * buckets[i]
            return res
    

    Waning: to be honest, no one will use this to solve real-world problem. will waste lot of memory space.
    (没什么人会用)

    Test Code Link

    Radix Sort(基数排序)

    Main Idea: distribute the data into buckets based on their unit digit. and collect all of them, and then redistribute them based on their tens digit, continue doing this way.
    (依次用原始数据各项的个十百等数位进行映射,每次映射后,再将桶里的数据依次提出来,覆盖表原来的数据,重复下去直到所有数位都用完)

    Feature: Stable O(n*k)

        def radix_sort(arr):
            digit = 0
            max_digit = 1
            max_value = max(arr)
    
            while 10 ** max_digit < max_value:
                max_digit += 1
    
            while digit < max_digit:
                buckets = [[] for _ in range(10)]
                for i in arr:
                    num = int((i / 10 ** digit) % 10)
                    buckets[num].append(i)
    
                temp_result = []
                for bucket in buckets:
                    temp_result.extend(bucket)
    
                arr = temp_result
                digit += 1
            return arr
    

    Warning: What should I say, same as the counting sort, even though it has some improvement.
    (跟计数排序一样,没人用)

    Test Code Link

    笔记完整代码Github: https://github.com/AaronYang2333/CSCI_570/wiki
    持续更新!

  • 相关阅读:
    POJ2481:Cows(树状数组)
    Go语言用堆排序的方法进行一千万个int随机数排序.
    【一】注入框架RoboGuice使用:(A brief example of what RoboGuice does)
    POJ3067:Japan(树状数组求逆序对)
    Android开发之ListView实现不同品种分类分隔栏的效果(非ExpandableListView实现)
    躁动不安的const
    JAVA实现RSA加密解密 非对称算法
    Cocos2d坐标系具体解释
    leetcode_Product of Array Except Self
    IIS2008配置URlRewriter
  • 原文地址:https://www.cnblogs.com/sight-tech/p/13111555.html
Copyright © 2011-2022 走看看