zoukankan      html  css  js  c++  java
  • 冒泡排序,选择排序,插入排序,希尔排序,归并排序,快速排序 实现

    1.冒泡排序

    # 优化版 优化有序的情况,最优时间复杂度O(n)
    
    def bubble_sort(alist):
        # 外层循环控制比较几轮
        n = len(alist)
        for j in range(n - 1):
            # 定义计数器
            count = 0
            # 内存循环控制交换
            # -j是不再换已经排好的
            for i in range(n - 1 - j):
                # 若前一个比后一个大,则换
                if alist[i] > alist[i + 1]:
                    alist[i], alist[i + 1] = alist[i + 1], alist[i]
                    # 计数器
                    count += 1
            if count == 0:
                return

     2.选择排序

    # alist = [3, 11, 26, 26,7, 3, 9, 4]
    # 选择排序把数据当成2部分
    # alist = [3,        11, 26, 26,7, 9, 4]
    # alist = [3, 4     11, 26, 26,7, 9]
    # 怎么找到最小值? 索引min = 0
    # 最终min = 0
    
    # min = 1开始
    # min = 6
    # alist[1] alist[6]
    
    def select_sort(alist):
        n = len(alist)
        # 外层控制比较几轮
        for j in range(n - 1):
            min_index = j
            # 内层控制元素比较和更新索引
            for i in range(j + 1, n):
                # 进行比较
                if alist[min_index] > alist[i]:
                    # 更新索引
                    min_index = i
            # 退出循环后,交换数据
            alist[j], alist[min_index] = alist[min_index], alist[j]
    
    
    if __name__ == '__main__':
        li = [3, 11, 26, 26, 7, 3, 9, 4]
        print(li)
        select_sort(li)
        print(li)

    3.插入排序

    # 插入排序
    def insert_sort(alist):
        n = len(alist)
        # 外层循环控制从右边取多少元素
        for j in range(1, n):
            # i = [123...]
            i = j
            # 内存循环
            while i > 0:
                if alist[i] < alist[i - 1]:
                    alist[i], alist[i - 1] = alist[i - 1], alist[i]
                    # 控制循环结束
                    i -= 1
                else:
                    break
    
    
    if __name__ == '__main__':
        li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
        print(li)
        insert_sort(li)
        print(li)

    4.希尔排序

    # 希尔排序
    def shell_sort(alist):
        n = len(alist)
        # 假如gap = n/2
        gap = n // 2
        
        # 控制gap 不断缩小
        while gap >= 1:
            # 插入排序
            # 这里从gap开始到最后比较
            for j in range(gap,n):
                # i = [gap,gap+1,...]
                i = j
                while i > 0:
                    if alist[i] < alist[i-gap]:
                        alist[i],alist[i-gap] = alist[i-gap],alist[i]
                        i -= gap
                    else:
                        break
            #缩短gap
            gap //= 2

    5.快速排序

    # 快排
    # first理解为第一个位置的索引,last是最后位置索引
    def quick_sort(alist, first, last):
        # 递归终止条件
        if first >= last:
            return
    
            # 设置第一个元素为中间值
        mid_value = alist[first]
        # low指向
        low = first
        # high
        high = last
        # 只要low小于high就一直走
        while low < high:
            # high大于中间值,则进入循环
            while low < high and alist[high] >= mid_value:
                # high往左走
                high -= 1
            # 出循环后,说明high小于中间值,low指向该值
            alist[low] = alist[high]
            # high走完了,让low走
            # low小于中间值,则进入循环
            while low < high and alist[low] < mid_value:
                # low向右走
                low += 1
            # 出循环后,说明low大于中间值,high指向该值
            alist[high] = alist[low]
        # 退出整个循环后,low和high相等
        # 将中间值放到中间位置
        alist[low] = mid_value
        # 递归
        # 先对左侧快排
        quick_sort(alist, first, low - 1)
        # 对右侧快排
        quick_sort(alist, low + 1, last)
    
    
    if __name__ == '__main__':
        li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
        print(li)
        quick_sort(li, 0, len(li) - 1)
        print(li)

    6.归并排序

    # 归并排序
    def merge_sort(alist):
        n = len(alist)
    
        # 递归结束条件
        if n <= 1:
            return alist
    
        # 中间位置
        mid = n // 2
        # 递归拆分左侧
        left_li = merge_sort(alist[:mid])
        # 递归拆分右侧
        right_li = merge_sort(alist[mid:])
        # 需要2个游标,分别指向左列表和右列表第一个元素
        left_point, right_point = 0, 0
        # 定义最终返回的结果集
        result = []
        # 循环合并数据
        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__':
        li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
        print(li)
        sort_li = merge_sort(li)
        print(li)
        print(sort_li)
  • 相关阅读:
    Android OCR 之 tesseract
    抛砖引玉 之 谁动了我的流量(0权限上传数据)
    退伍一年了
    android 通过 Hessian 与 j2ee 服务端交互
    Arduino 入手
    抛砖引玉 之 谁动了我的隐私(android用户隐私窥探)
    如何关注那些有价值的微博
    关于培训和外包20111027
    ASP.NET实现Cookie功能的三个基本操作(写入,读取,删除)
    提高你开发效率的十五个Visual Studio 2010使用技巧
  • 原文地址:https://www.cnblogs.com/hude/p/12939935.html
Copyright © 2011-2022 走看看