比较各种常见的排序算法(python)

  1. 选择排序0(n^2)

    def select_sort(li):
        li_new = []  # 用于存储排序完成的结果
        for i in range(len(li)):
            min_val = min(li)  # 找出最小值
            li_new.append(min_val)
            li.remove(min_val)  # 在原列表中删除当前最小值
    
        return li_new
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))  # 设定将[0,500)之间的数随机打乱
        random.shuffle(li)
        print(select_sort(li))
        end = time.time()
        print(end - start)
    

  2. 冒泡排序0(n^2)

    def bubble_sort(li):
        for i in range(len(li) - 1):
            flag = False  # 设定flag判断是否发生交换
            for j in range(len(li) - i - 1):
                if li[j] > li[j + 1]:  # 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
                    li[j], li[j + 1] = li[j + 1], li[j]
                    flag = True
            if not flag:  # 如果一开始输入的列表是排好顺序的,那么直接返回
                return li
        return li
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))
        random.shuffle(li)  # 设定将[0,500)之间的数随机打乱
        print(bubble_sort(li))
        end = time.time()
        print(end - start)
    

  3. 归并排序O (nlogn)

    def merg_sort(li):
        # 分解
        n = len(li)
        # 递归的出口分解到最小
        if n <= 1:
            return li
        else:
            mid = n // 2
            left_li = merg_sort(li[0:mid])
            right_li = merg_sort(li[mid:])
    
        # 合并
        # 排序结果链表
        result = []  # 最终返回的列表
        left_point, right_point = 0, 0
        while left_point < len(left_li) and right_point < len(right_li):  # 左指针和右指针都没超过相应列表的长度
            if left_li[left_point] < right_li[right_point]:  # 添加两个列表中较小的值
                result.append(left_li[left_point])  # 左列表的值较小时
                left_point += 1  # 移动指针
            else:  # 右列表的值较小时
                result.append(right_li[right_point])
                right_point += 1
    
        # 退出循环,将不为空的列表元素加到列表
        result += left_li[left_point:]
        result += right_li[right_point:]
    
        return result
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))
        random.shuffle(li)
    
        print(merg_sort(li))
        end = time.time()
        print(end - start)
    

  4. 插入排序O (n^2)

    def insert_sort(li):
        for i in range(1, len(li)):  # i为已经排序完成的下一个数的下标
            tem = li[i]  # 用于存储下一个数的值
            j = i - 1  # j为已经排完序的下标
            while j >= 0 and li[j] > tem:  # 从后往前找
                li[j + 1] = li[j]  # 如果li[i]小于li[j]
                j -= 1
            li[j + 1] = tem
        return li
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))
        random.shuffle(li)  # 设定将[0,500)之间的数随机打乱
        print(insert_sort(li))
        end = time.time()
        print(end - start)
    

  5. 希尔排序O(nlogn)~O(n2)

    # 原理同插入排序相同
    def insert_sort_gap(li, gap):
        for i in range(gap, len(li)):
            tem = li[i]
            j = i - gap
            while j >= 0 and li[j] > tem:  # 从后往前找
                li[j + gap] = li[j]  # 如果li[j + gap]小于li[j]
                j -= gap
            li[j + gap] = tem
    
    
    def shell_sort(li):
        d = len(li) // 2  # 将gap初始设定为列表长度的一半
        while d >= 1:  # 当d < 1时结束循环
            insert_sort_gap(li, d)
            d //= 2
        return li
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))
        random.shuffle(li)  # 设定将[0,500)之间的数随机打乱
        print(shell_sort(li))
        end = time.time()
        print(end - start)
    
  6. 堆排序O(nlogn)

    # 堆排序
    
    def sift(li, low, high):
        i = low  # i最开始指向根节点
        j = 2 * i + 1  # j开始是左孩子
        tem = li[low]  # 把堆顶存起来
        while j <= high:  # 只要j位置有数
            if j < high and li[j] < li[j + 1]:  # 如果右孩子有且比较大
                j = j + 1  # j指向右孩子
            if li[j] > tem:
                li[i] = li[j]
                i = j  # 往下看一层
                j = 2 * i + 1
            else:  # tem 更大,把tem放到i的位置上
                li[i] = tem  # 把tem放到某一级领导位置上
                break
        else:
            li[i] = tem  # 把tem放到叶子结点上
    
    
    def heap_sort(li):
        n = len(li)
        for i in range(n // 2 - 1, -1, -1):
            # i表示建堆的时候调整的部分的根的下标
            sift(li, i, n - 1)
        # 建堆完成了
        for i in range(n - 1, -1, -1):
            # i指向当前堆的最后一个元素
            li[0], li[i] = li[i], li[0]
            sift(li, 0, i - 1)
        return li
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))
        random.shuffle(li)  # 设定将[0,500)之间的数随机打乱
        print(heap_sort(li))
        end = time.time()
        print(end - start)
    

  7. 快速排序O(nlogn)~ O(n^2)

    # 快速排序
    def quick_sort(li, left, right):
        tem = li[left]
        while left < right:
            while left < right and li[right] >= tem:  # 从右边找比tem小的数
                right -= 1  # 往左走一步
            li[left] = li[right]  # 把右边的值写到左边的空位上
            while left < right and li[left] <= tem:  # 从左边找比tem大的数
                left += 1
            li[right] = li[left]  # 把左边的值写到右边的空位上
        li[left] = tem  # 把tem归位
        return left
    
    
    def main(li, left, right):
        if left < right:  # 当个区间只有一个数时,排序完成
            mid = quick_sort(li, left, right)
            main(li, left, mid - 1)
            main(li, mid + 1, right)
        return li
    
    
    if __name__ == '__main__':
        import random
        import time
    
        start = time.time()
        li = list(range(500))
        random.shuffle(li)
        print(main(li, 0, len(li) - 1))
        end = time.time()
        print(end - start)
    

    (由于数据量设置500太小,以上所得皆为5000个数据的时间)

猜你喜欢

转载自blog.csdn.net/weixin_64890968/article/details/131721169