1. 前言

排序算法(英语:Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。

2. 代码

class Sort(object):

    def bubble_sort(self, li):
        """
        冒泡排序
        冒泡排序(Bubble Sort)是一种比较简单的排序算法,它重复地走访过要排序的元素,
        依次比较相邻两个元素,如果它们的顺序错误就把他们调换过来,直到没有元素再需要交换,排序完成。
        其核心思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序记录为止。
        """
        n = len(li)
        for i in range(n):
            flag = False
            # 内循环找到最大的数放置末尾
            for j in range(n - i - 1):
                if li[j] > li[j + 1]:
                    li[j], li[j + 1] = li[j + 1], li[j]
                    flag = True
            if not flag:
                break
        return li

    def select_sort(self, li):
        """
        选择排序
        选择排序(Selection Sort)的原理,每一轮从待排序的记录中选出最小的元素,
        存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小元素,然后放到已排序的序列的末尾。
        以此类推,直到全部待排序的数据元素的个数为零。得到数值从小到达排序的数据序列。
        选择排序每次选出最小(最大)的元素,因此需要遍历 n-1 次。

        核心思想是:对尚未完成排序的所有元素,从头到尾比一遍,记录下最小的那个元素的下标,
        也就是该元素的位置。再把该元素交换到当前遍历的最前面。
        """
        n = len(li)
        for i in range(n - 1):
            # 假设第一个元素为最小元素
            min_index = i
            # 从i+1位置到末尾选择出最小数据 - 遍历未排序区域元素,以此和未排序区域的第一个元素做对比
            for j in range(i + 1, n):
                if li[j] < li[min_index]:
                    min_index = j
            # 交换位置 - 如果选择出的数据不在正确位置,进行交换
            if min_index != i:
                li[min_index], li[i] = li[i], li[min_index]
        return li

    def insert_sort(self, li):
        """
        插入排序
        插入排序(Insertion Sort)就是每一步都将一个需要排序的数据按其大小插入到已经排序的数据序列中的适当位置,直到全部插入完毕。
        插入排序如同打扑克牌一样,每次将后面的牌插到前面已经排好序的牌中。
        基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。
        """
        n = len(li)
        for i in range(1, n):
            # 从第i个元素开始向前比较,如果小于前一个元素,交换位置
            for j in range(i, 0, -1):
                if li[j] < li[j - 1]:
                    li[j], li[j - 1] = li[j - 1], li[j]
                else:
                    break
        return li

    def quick_sort(self, arr):
        """
        快速排序
        快速排序算法的核心思想:通过一趟排序将待排记录分割成独立的两部分,
        其中一部分记录的关键字均比另一部分记录的关键字小,然后分别对这两部分继续进行排序,以达到整个记录集合的排序目的。
        """
        # 基线条件:数组为空或只有一个元素
        if len(arr) < 2:
            return arr
        pivot = arr[0]  # 选择第一个元素作为基准点
        less = [i for i in arr[1:] if i <= pivot]  # 所有小于等于基准点的元素
        greater = [i for i in arr[1:] if i > pivot]  # 所有大于基准点的元素
        return self.quick_sort(less) + [pivot] + self.quick_sort(greater)  # 递归调用快排并合并结果

    def quick_sort_2(self, li, start, end):
        """
        快速排序第二种写法
        """
        if start >= end:
            return li
        mid = li[start]
        low = start
        high = end
        while low < high:
            # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
            while low < high and li[high] >= mid:
                high -= 1
            # 将high指向的元素放到low的位置上
            li[low] = li[high]

            # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
            while low < high and li[low] < mid:
                low += 1
            # 将low指向的元素放到high的位置上
            li[high] = li[low]

        # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
        # 将基准元素放到该位置
        li[low] = mid

        # 对基准元素左边的子序列进行快速排序
        self.quick_sort(li, start, low - 1)
        # 对基准元素右边的子序列进行快速排序
        self.quick_sort(li, low + 1, end)
        return li


if __name__ == '__main__':
    sort = Sort()
    print(sort.select_sort([4, 2, 3, 7, 8, 5, 6, 1, 101, 0, 1, 2, 1]))

3. 常见排序算法效率比较

Python - 经典排序算法【冒泡、选择、插入、排序】_数据